pulp / pulp/pulpcore

Support an optional per-call pubkey_fingerprint on the base SigningService.sign()

Open
#7,942 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Feature
Dominant language
Python
Stars
598
Forks
168
Avg merge
1d 4h
Merged PRs (30d)
86

Description

Is your feature request related to a problem? Please describe.

Today, metadata signing services bind one key per service. The base SigningService.sign() signs with whatever key the service was created with, with no per-call override. Both metadata services inherit this unchanged: AsciiArmoredDetachedSigningService (pulpcore, RPM repomd.xml) and AptReleaseSigningService (pulp_deb, deb Release). Package signing already solved this — RpmPackageSigningService.sign() takes a pubkey_fingerprint and injects it as PULP_SIGNING_KEY_FINGERPRINT, so one service signs for many keys.

As a result, signing repositories' metadata with different keys requires a separate signing service per key. In containerized deployments each new key means a new add-signing-service registration (on-disk script, importable GPG key, full validate() run) — effectively a deployment change per key. This is the pain behind pulpcore #6733 and pulp/pulp_rpm#4052.

Describe the solution you'd like

Mirror the package-signing pattern on the shared base method so both metadata services benefit:

  1. Add an optional pubkey_fingerprint=None kwarg to the base SigningService.sign() (and asign()). When set, it overrides PULP_SIGNING_KEY_FINGERPRINT; when unset, it falls back to the service's own key (today's behavior). AsciiArmoredDetachedSigningService and AptReleaseSigningService inherit this automatically, since neither overrides sign().
  2. Plugins add a nullable metadata_signing_fingerprint on their repository models (parallel to package_signing_fingerprint) and forward it from the publish task.

A deployment then registers one generic metadata signing service per format at boot and selects the key per publish via the repository's fingerprint.

FWIW - this solution is backwards compatible: _env_variables already injects PULP_SIGNING_KEY_FINGERPRINT, so this only overrides a value already passed; the kwarg is optional and defaults to None (unlike RpmPackageSigningService.sign(), which made it mandatory); the repo field is nullable; and validate() is unchanged since it signs with no fingerprint.

Describe alternatives you've considered

  • A writable signing-service create/delete REST API (pulpcore #6733). Still one service per key, still carries the on-disk-script + keyring + validate() side effects, and re-opens the arbitrary-script-path security concern that stalled that issue.
  • Invoking add-signing-service at runtime. Operationally fragile, couples callers to Pulp's pod internals, and produces a sprawl of per-key services.
  • Keeping the fingerprint purely in the plugin (as pulp/pulp_rpm#4052 leaned). The repo field is inert unless the base sign() honors a per-call fingerprint — which is why this pulpcore change is the prerequisite.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at the base SigningService.sign() and asign() methods, then compare RpmPackageSigningService.sign() and its PULP_SIGNING_KEY_FINGERPRINT handling. Done means an optional fingerprint overrides the service environment value while None preserves current behavior, with inherited metadata signing services benefiting without their own sign() overrides.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend, security
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.