Skip to content

feat(sigstore): typed credentials for sigstore binding (Phase 2)#324

Draft
morri-son wants to merge 25 commits into
feat/cosign-signing-handler-1-sigstorefrom
feat/sigstore-typed-credentials
Draft

feat(sigstore): typed credentials for sigstore binding (Phase 2)#324
morri-son wants to merge 25 commits into
feat/cosign-signing-handler-1-sigstorefrom
feat/sigstore-typed-credentials

Conversation

@morri-son

Copy link
Copy Markdown
Owner

What this PR does / why we need it

Phase 2 typed signing bindings for Sigstore (ADR 0018)

Introduces typed credential and identity specs for Sigstore keyless signing:

  • OIDCIdentityToken/v1 — OIDC token credential with token + tokenFile fields
  • TrustedRoot/v1 — Sigstore trust material credential with trustedRootJSON + trustedRootJSONFile fields
  • SigstoreSigner/v1 — consumer identity type for signing (accepts OIDCIdentityToken)
  • SigstoreVerifier/v1 — consumer identity type for verification (accepts TrustedRoot)

The handler is migrated to use FromDirectCredentials internally, and the placeholder types in signing/v1alpha1/ are removed.

Follows the exact pattern established by open-component-model#2418 (RSA typed credentials).

Which issue(s) this PR fixes

Contributes: open-component-model/ocm-project#988

Stacks on: open-component-model#2344

Testing

How to test the changes

Unit tests only. All existing handler tests continue to pass with the new typed credential internals.

cd bindings/go/sigstore && go test ./... -count=1
Verification
  • I have added/updated tests for my changes (see Test Requirements)
  • Tests pass locally (go test ./...)
  • My changes do not decrease test coverage
  • Lint passes (golangci-lint run ./... — 0 issues)

Add a signing handler that delegates to cosign for signing and
verifying OCM component versions using Sigstore infrastructure.

Includes:
- Cosign binary management with download, caching, and checksum verification
- Sign and verify operations via subprocess execution
- OIDC credential plugin integration for keyless signing
- Stderr scrubbing to prevent secret leakage in error messages
- Security hardening: input validation, env isolation, HTTPS enforcement
- Comprehensive unit test coverage

Signed-off-by: Gerald Morrison (SAP) <gerald.morrison@sap.com>
…oreVerifier

Consumer identity types describe WHAT a consumer IS, not what credential
it needs. The previous names (OIDCIdentityToken/v1alpha1, TrustedRoot/v1alpha1)
described credential types, not consumer identities.

- Rename IdentityTypeOIDCIdentityToken → CredentialTypeOIDCIdentityToken
- Rename IdentityTypeTrustedRoot → CredentialTypeTrustedRoot
- Add SigstoreSigner/v1alpha1 and SigstoreVerifier/v1alpha1 as proper
  consumer identity types in handler/internal/credentials/ (mirrors RSA pattern)
- Update handler to use new identity types
- Update tests

Signed-off-by: Gerald Morrison (SAP) <gerald.morrison@sap.com>
Add +ocm:jsonschema-gen=true markers to SignConfig and VerifyConfig,
aligning with the RSA handler's approach. This enables CLI introspection
via `ocm describe types` for sigstore configuration types.

Generated schemas:
- schemas/SignConfig.schema.json
- schemas/VerifyConfig.schema.json

Signed-off-by: Gerald Morrison (SAP) <gerald.morrison@sap.com>
Fix the Sigstore example configuration section to use correct terminology:
- Consumer identity types: SigstoreSigner/v1alpha1, SigstoreVerifier/v1alpha1
- Credential plugin: OIDCIdentityTokenProvider/v1alpha1
- Show three signing credential cases: plugin (public-good), plugin (private
  infra with custom issuer/clientID), and direct token (CI)
- Update sequence diagram annotations

Signed-off-by: Gerald Morrison (SAP) <gerald.morrison@sap.com>
Clarify that either a direct credential (Credentials/v1 with token key)
or a credential plugin (OIDCIdentityTokenProvider/v1alpha1) can provide
the required OIDC identity token.

Signed-off-by: Gerald Morrison (SAP) <gerald.morrison@sap.com>
Signed-off-by: Gerald Morrison (SAP) <gerald.morrison@sap.com>
Avoids recompiling the version regex on every call to
parseCosignVersionOutput.

Signed-off-by: Gerald Morrison (SAP) <gerald.morrison@sap.com>
runtime.GOOS and runtime.GOARCH are compile-time constants; no need to
recompute cosignBinaryName on every call to ensureOrDownloadCosign.

Signed-off-by: Gerald Morrison (SAP) <gerald.morrison@sap.com>
Pass the caller's context instead of creating context.Background().
This respects parent cancellation and deadlines during version detection.

Signed-off-by: Gerald Morrison (SAP) <gerald.morrison@sap.com>
Capture stdout from cosign subprocesses and log at debug level
instead of silently discarding it.

Signed-off-by: Gerald Morrison (SAP) <gerald.morrison@sap.com>
Document that ensureOrDownloadCosign requires serialized access (caller
holds mutex), that Handler is safe for concurrent use after construction,
and that DefaultExecutor serializes resolution but allows concurrent Run.
Remove misleading concurrency/TOCTOU comment block that implied concurrent
use was expected on the download function itself.

Signed-off-by: Gerald Morrison (SAP) <gerald.morrison@sap.com>
Use io.Reader instead of []byte for more idiomatic Go and to support
streaming larger payloads without full materialization in memory.

Signed-off-by: Gerald Morrison (SAP) <gerald.morrison@sap.com>
Replace the hardcoded package-level downloadHTTPClient with an
injectable *http.Client on DefaultExecutor via WithHTTPClient option.
This allows consumers (CLI, controller) to configure timeouts and
transport settings through the project's dynamic HTTP client system.

The default remains a 2-minute timeout client for backward compatibility.

Signed-off-by: Gerald Morrison (SAP) <gerald.morrison@sap.com>
Reduce type documentation to two lines max per coding conventions.
Align NewDefaultExecutor with the project's nil-check-after-apply
pattern for functional options defaults.

Signed-off-by: Gerald Morrison (SAP) <gerald.morrison@sap.com>
Make the API contract explicit: callers must call Ensure() to resolve
the cosign binary before calling Run(). Run() returns ErrNotResolved
if called without prior Ensure(). This removes hidden lazy initialization
from Run() and makes the lifecycle clear for consumers (CLI, controller).

Signed-off-by: Gerald Morrison (SAP) <gerald.morrison@sap.com>
…en override

Replace the restrictive environment allowlist with a minimal denylist
(LD_PRELOAD, DYLD_INSERT_LIBRARIES, LD_LIBRARY_PATH, BASH_ENV). All
other environment variables — including SIGSTORE_*, COSIGN_*, TUF_* —
are now passed through to the cosign subprocess.

Ambient SIGSTORE_ID_TOKEN takes priority over OCM credential tokens.
The OCM credential token is used as fallback when no ambient token exists.
This enables workload identity and CI environments where tokens are
injected via environment without requiring OCM credential configuration.

Signed-off-by: Gerald Morrison (SAP) <gerald.morrison@sap.com>
…on workflow

Allow ACTIONS_ID_TOKEN_REQUEST_TOKEN as an ambient credential source so
cosign can use GitHub's OIDC endpoint for keyless signing without an
explicit token in the credential map.

Add unit tests for ambient SIGSTORE_ID_TOKEN and ACTIONS_ID_TOKEN_*
pass-through, plus a scaffolding-based integration test that signs with
the token set purely via environment variable.

Restore the sigstore-integration.yml workflow (lost during force-push)
to run E2E tests against the sigstore scaffolding cluster in CI.

Signed-off-by: Gerald Morrison (SAP) <gerald.morrison@sap.com>
Signed-off-by: Gerald Morrison (SAP) <gerald.morrison@sap.com>
The sigstore scaffolding (Trillian, Knative) does not reliably start on
ARM64 GitHub runners — the log-server Knative service times out during
setup. Switch back to ubuntu-latest (amd64) where the scaffolding works.

Signed-off-by: Gerald Morrison (SAP) <gerald.morrison@sap.com>
Signed-off-by: Gerald Morrison (SAP) <gerald.morrison@sap.com>
Signed-off-by: Gerald Morrison (SAP) <gerald.morrison@sap.com>
Signed-off-by: Gerald Morrison (SAP) <gerald.morrison@sap.com>
Signed-off-by: Gerald Morrison (SAP) <gerald.morrison@sap.com>
…ped specs

Signed-off-by: Gerald Morrison (SAP) <gerald.morrison@sap.com>
)

// Deprecated: Use signeridentityv1.V1Alpha1Type instead.
var IdentityTypeSigstoreSigner = signeridentityv1.V1Alpha1Type

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these can be consts right?

@morri-son morri-son May 6, 2026

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can't be consts since runtime.Type is a struct - but turns out nothing actually uses these vars (all consumers moved to the typed identity packages as part of the PR). Removed the whole file instead.

@matthiasbruns matthiasbruns left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like I have imagined it <3 just a tiny nit

Remove the internal/credentials package that contained only unused
deprecated var aliases for identity types. These were dead code with
no consumers.

Addresses review feedback on PR #324.

Signed-off-by: Gerald Morrison (SAP) <gerald.morrison@sap.com>
@morri-son morri-son force-pushed the feat/cosign-signing-handler-1-sigstore branch 3 times, most recently from 37e7134 to e208e44 Compare May 11, 2026 13:59
@morri-son morri-son force-pushed the feat/cosign-signing-handler-1-sigstore branch 3 times, most recently from 5a7a0d2 to 72f2e17 Compare May 12, 2026 06:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants