feat(cli): integrate cosign signing handler [2/2]#2346
Conversation
✅ Deploy Preview for ocm-website ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds Sigstore keyless signing/verification: interactive PKCE S256 OIDC flow (loopback callback + browser), a builtin OIDC credential plugin, CLI signer/verifier spec help/examples and tests, integration test + Taskfile task, plugin wiring, and dependency updates for go-oidc and sigstore bindings. ChangesSigstore keyless signing flow (single cohesive DAG)
Sequence DiagramsequenceDiagram
participant User
participant CLI as OCM CLI
participant LocalServer as Local Callback Server
participant Browser as System Browser
participant OIDC as OIDC Provider
participant TokenEP as Token Endpoint
participant Sigstore as Sigstore (Fulcio/Rekor/Timestamp)
User->>CLI: ocm sign --signer-spec sigstore.yaml
CLI->>CLI: Load signer-spec and OIDCProvider config
CLI->>LocalServer: Start local 127.0.0.1 callback server
CLI->>Browser: Open auth URL (PKCE, state, nonce)
Browser->>OIDC: Authorization request
User->>OIDC: Authenticate
OIDC->>Browser: Redirect to callback with code & state
Browser->>LocalServer: GET /auth/callback?code=...&state=...
LocalServer->>LocalServer: Validate state, respond success page
LocalServer->>CLI: Deliver authorization code
CLI->>TokenEP: Exchange code + PKCE verifier for id_token
TokenEP->>CLI: Return id_token
CLI->>CLI: Verify id_token nonce & signature
CLI->>Sigstore: Submit signing request with id_token
Sigstore->>CLI: Return signature record
CLI->>User: Report success / store signature
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
fabianburth
left a comment
There was a problem hiding this comment.
Please be more careful with your PR hygiene!
I did not review the oidc flow in detail. I'd like to understand how detailed of a review I need to do here. Is this a battle tested copy from another established project that we copied to avoid the dependencies or is this a custom implementation?
59448c2 to
7bb54e3
Compare
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (2)
cli/internal/plugin/builtin/oidc/oidc_plugin_test.go (1)
43-44: Consider using constants for default values in test assertions.The test hardcodes the expected defaults (
"https://oauth2.sigstore.dev/auth","sigstore") rather than referencingoidcflow.DefaultIssuerandoidcflow.DefaultClientID. If the defaults change in the future, this test would silently pass with stale values.♻️ Proposed fix
+import "ocm.software/open-component-model/cli/internal/oidcflow" + func Test_OIDCPlugin_GetConsumerIdentity_Defaults(t *testing.T) { // ... - r.Equal("https://oauth2.sigstore.dev/auth", id[configKeyIssuer]) - r.Equal("sigstore", id[configKeyClientID]) + r.Equal(oidcflow.DefaultIssuer, id[configKeyIssuer]) + r.Equal(oidcflow.DefaultClientID, id[configKeyClientID]) }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@cli/internal/plugin/builtin/oidc/oidc_plugin_test.go` around lines 43 - 44, The test assertions use hardcoded strings for issuer and client ID; change them to reference the package constants oidcflow.DefaultIssuer and oidcflow.DefaultClientID (instead of the literal "https://oauth2.sigstore.dev/auth" and "sigstore") in the assertions that check id[configKeyIssuer] and id[configKeyClientID] so the test stays correct if defaults change.cli/internal/oidcflow/oidcflow_test.go (1)
28-43: Test validates PKCE struct but not thenewPKCEconstructor.This test manually constructs a
pkcestruct and validates its methods, but doesn't testnewPKCE()which includes the provider claims check and verifier generation. Consider adding a test that exercisesnewPKCEwith a mock provider if S256 support validation is critical.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@cli/internal/oidcflow/oidcflow_test.go` around lines 28 - 43, Add a test that calls newPKCE rather than constructing pkce directly: create a mock OIDC provider (or stub its provider.Claims) that advertises "S256" in the "code_challenge_methods_supported" claim, call newPKCE(ctx, provider) and assert it returns a non-nil *pkce with a generated verifier (non-empty and expected length), verify the challenge equals base64.RawURLEncoding.EncodeToString(sha256.Sum256(verifier)[:]) and that authURLOpts() and tokenURLOpts() return the expected counts; also add a negative case where the provider does not list "S256" and assert newPKCE returns an error.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@cli/cmd/setup/setup.go`:
- Around line 117-121: The anonymous credential-plugin factory must guard
against nil before dereferencing: in the func(_ context.Context, typed
runtime.Typed) (credentials.CredentialPlugin, error) block check that typed !=
nil and typed.GetType() != nil before calling GetName(); if either is nil return
a clear validation error (e.g., fmt.Errorf("invalid credential plugin: missing
type")), otherwise compare typed.GetType().GetName() to oidc.OIDCPluginType and
return &oidc.OIDCPlugin{} or the existing fmt.Errorf for unknown types.
In `@cli/docs/reference/ocm_sign_component-version.md`:
- Around line 144-145: Update the doc wording that currently claims "The
OIDCProvider plugin checks SIGSTORE_ID_TOKEN env var first (CI/automation), then
falls back to an interactive browser-based OIDC flow": remove that env-var-first
statement and replace it with a short sentence that the OIDCProvider plugin now
uses the browser-based OIDC flow as the primary token acquisition method and no
longer relies on SIGSTORE_ID_TOKEN for first-class token sourcing; specifically
edit the paragraph referencing OIDCProvider and SIGSTORE_ID_TOKEN to reflect the
new behavior (mention OIDCProvider and SIGSTORE_ID_TOKEN by name) and ensure the
doc does not describe the removed env-var-first behavior.
In `@cli/internal/oidcflow/oidcflow.go`:
- Around line 340-341: The Windows branch passes rawURL unquoted to
exec.CommandContext, which causes cmd.exe to split on ampersands; update the
call that builds cmd (the exec.CommandContext invocation in the case "windows"
block) to pass a quoted URL argument (wrap rawURL in double quotes before
passing it, e.g. construct a quotedRawURL from rawURL) so the start "" "URL"
form is used and URLs with & or other special chars are preserved.
---
Nitpick comments:
In `@cli/internal/oidcflow/oidcflow_test.go`:
- Around line 28-43: Add a test that calls newPKCE rather than constructing pkce
directly: create a mock OIDC provider (or stub its provider.Claims) that
advertises "S256" in the "code_challenge_methods_supported" claim, call
newPKCE(ctx, provider) and assert it returns a non-nil *pkce with a generated
verifier (non-empty and expected length), verify the challenge equals
base64.RawURLEncoding.EncodeToString(sha256.Sum256(verifier)[:]) and that
authURLOpts() and tokenURLOpts() return the expected counts; also add a negative
case where the provider does not list "S256" and assert newPKCE returns an
error.
In `@cli/internal/plugin/builtin/oidc/oidc_plugin_test.go`:
- Around line 43-44: The test assertions use hardcoded strings for issuer and
client ID; change them to reference the package constants oidcflow.DefaultIssuer
and oidcflow.DefaultClientID (instead of the literal
"https://oauth2.sigstore.dev/auth" and "sigstore") in the assertions that check
id[configKeyIssuer] and id[configKeyClientID] so the test stays correct if
defaults change.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 3a33ec4a-ec19-41ec-8e85-a48ace32affc
⛔ Files ignored due to path filters (2)
cli/go.sumis excluded by!**/*.sumcli/integration/go.sumis excluded by!**/*.sum
📒 Files selected for processing (15)
cli/cmd/cmd_test.gocli/cmd/setup/setup.gocli/cmd/sign/component-version/cmd.gocli/cmd/verify/component-version/cmd.gocli/docs/reference/ocm_sign_component-version.mdcli/docs/reference/ocm_verify_component-version.mdcli/go.modcli/integration/download_resource_integration_test.gocli/integration/go.modcli/internal/oidcflow/oidcflow.gocli/internal/oidcflow/oidcflow_test.gocli/internal/plugin/builtin/builtin.gocli/internal/plugin/builtin/oidc/oidc_plugin.gocli/internal/plugin/builtin/oidc/oidc_plugin_test.gocli/internal/plugin/builtin/oidc/register.go
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
cli/integration/Taskfile.yml (1)
20-20: QuoteSIGSTORE_ENV_FILEin shell expressions.Line 20 and Line 27 use an unquoted path. Quoting avoids word-splitting/globbing edge cases and makes the task more robust.
♻️ Proposed fix
- - sh: '[ -f {{.SIGSTORE_ENV_FILE}} ]' + - sh: '[ -f "{{.SIGSTORE_ENV_FILE}}" ]' @@ - . {{.SIGSTORE_ENV_FILE}} + . "{{.SIGSTORE_ENV_FILE}}"Also applies to: 27-27
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@cli/integration/Taskfile.yml` at line 20, The shell checks using the SIGSTORE_ENV_FILE template variable are unquoted which can break on paths with spaces or glob characters; update the sh expressions that use SIGSTORE_ENV_FILE (the two occurrences in Taskfile.yml) to wrap the expanded value in quotes so the test uses "[ -f \"{{.SIGSTORE_ENV_FILE}}\" ]" (i.e., quote the template variable in both the check at the top and the second occurrence on line 27) to prevent word-splitting/globbing issues.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@cli/integration/sigstore_integration_test.go`:
- Around line 31-33: The skip guard currently checks stack.OIDCToken,
stack.SigningConfig and stack.TrustedRoot but omits the OIDC issuer/identity
needed later; update the condition to also verify SIGSTORE_OIDC_ISSUER and
SIGSTORE_OIDC_IDENTITY (or the corresponding fields stack.OIDCIssuer /
stack.OIDCIdentity if those are used) and call t.Skip with the same explanatory
message when any of them are empty so partially configured environments are
skipped cleanly.
---
Nitpick comments:
In `@cli/integration/Taskfile.yml`:
- Line 20: The shell checks using the SIGSTORE_ENV_FILE template variable are
unquoted which can break on paths with spaces or glob characters; update the sh
expressions that use SIGSTORE_ENV_FILE (the two occurrences in Taskfile.yml) to
wrap the expanded value in quotes so the test uses "[ -f
\"{{.SIGSTORE_ENV_FILE}}\" ]" (i.e., quote the template variable in both the
check at the top and the second occurrence on line 27) to prevent
word-splitting/globbing issues.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 0e6c43b4-274a-46b2-b0c4-442a22fa10fd
📒 Files selected for processing (3)
cli/integration/Taskfile.ymlcli/integration/sigstore_integration_test.gocli/internal/oidcflow/oidcflow_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
- cli/internal/oidcflow/oidcflow_test.go
There was a problem hiding this comment.
🧹 Nitpick comments (1)
cli/internal/oidcflow/oidcflow_test.go (1)
31-46: Auth URL test manually constructs parameters instead of using the same production code pathThe test at line 245 manually assembles URL query parameters, whereas the production code at
oidcflow.go:128-132callsoauth2.Config.AuthCodeURL()with options fromp.authURLOpts(). This means the test can pass even if the real auth URL construction path changes incorrectly. Refactor the test to use the same code path: callcfg.AuthCodeURL(state, append(p.authURLOpts(), oauth2.AccessTypeOnline, oidc.Nonce("test-nonce"))...)instead of manually building the query parameters.♻️ Suggested refactor
import ( "context" "crypto/sha256" "encoding/base64" "errors" "fmt" "net/http" "net/http/httptest" "net/url" "testing" "github.com/coreos/go-oidc/v3/oidc" + "golang.org/x/oauth2" "github.com/stretchr/testify/require" ) @@ func TestAuthURL_ContainsPKCEAndState(t *testing.T) { t.Parallel() r := require.New(t) - challenge := "test-challenge" - state := "random-state-value" - redirectURL := "http://127.0.0.1:12345/auth/callback" - - params := url.Values{ - "client_id": {"sigstore"}, - "redirect_uri": {redirectURL}, - "response_type": {"code"}, - "scope": {"openid email"}, - "state": {state}, - "code_challenge_method": {"S256"}, - "code_challenge": {challenge}, - "access_type": {"online"}, - "nonce": {"test-nonce"}, - } - authURL := "https://issuer.example.com/auth?" + params.Encode() + state := "random-state-value" + redirectURL := "http://127.0.0.1:12345/auth/callback" + p := &pkce{challenge: "test-challenge", verifier: "test-verifier"} + cfg := oauth2.Config{ + ClientID: "sigstore", + RedirectURL: redirectURL, + Scopes: []string{oidc.ScopeOpenID, "email"}, + Endpoint: oauth2.Endpoint{ + AuthURL: "https://issuer.example.com/auth", + }, + } + authURL := cfg.AuthCodeURL( + state, + append(p.authURLOpts(), oauth2.AccessTypeOnline, oidc.Nonce("test-nonce"))..., + ) parsed, err := url.Parse(authURL) r.NoError(err) @@ - r.Equal(challenge, q.Get("code_challenge")) + r.Equal(p.challenge, q.Get("code_challenge"))🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@cli/internal/oidcflow/oidcflow_test.go` around lines 31 - 46, The TestPKCEChallenge currently builds auth URL params manually; change it to exercise the real production path by creating an oauth2.Config and calling cfg.AuthCodeURL(state, append(p.authURLOpts(), oauth2.AccessTypeOnline, oidc.Nonce("test-nonce"))...), then parse the returned URL and assert the expected PKCE query parameters (code_challenge, code_challenge_method, etc.) and that tokenURLOpts still returns the expected token options via p.tokenURLOpts(); reference TestPKCEChallenge, pkce.authURLOpts, oauth2.Config.AuthCodeURL and p.tokenURLOpts when making the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@cli/internal/oidcflow/oidcflow_test.go`:
- Around line 31-46: The TestPKCEChallenge currently builds auth URL params
manually; change it to exercise the real production path by creating an
oauth2.Config and calling cfg.AuthCodeURL(state, append(p.authURLOpts(),
oauth2.AccessTypeOnline, oidc.Nonce("test-nonce"))...), then parse the returned
URL and assert the expected PKCE query parameters (code_challenge,
code_challenge_method, etc.) and that tokenURLOpts still returns the expected
token options via p.tokenURLOpts(); reference TestPKCEChallenge,
pkce.authURLOpts, oauth2.Config.AuthCodeURL and p.tokenURLOpts when making the
change.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 72ded86d-5438-4645-81ef-67bb2297054f
📒 Files selected for processing (3)
cli/internal/oidcflow/oidcflow.gocli/internal/oidcflow/oidcflow_test.godocs/adr/0016_sigstore_integration.md
✅ Files skipped from review due to trivial changes (2)
- docs/adr/0016_sigstore_integration.md
- cli/internal/oidcflow/oidcflow.go
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
cli/cmd/setup/setup.go (1)
117-124:⚠️ Potential issue | 🔴 Critical | ⚡ Quick winAdd a
typed.GetType() == nilguard before dereference.At Line 121,
typed.GetType().GetName()can panic whentypedis non-nil but missing type metadata.Suggested fix
func(_ context.Context, typed runtime.Typed) (credentials.CredentialPlugin, error) { - if typed == nil { + if typed == nil || typed.GetType() == nil { return nil, fmt.Errorf("no credential plugin found: missing type metadata") } - if typed.GetType().GetName() == oidc.OIDCPluginType { + if typed.GetType().GetName() == oidc.OIDCPluginType { return &oidc.OIDCPlugin{}, nil } return nil, fmt.Errorf("no credential plugin found for type %s", typed.GetType()) },Verify API contract and nilability with this read-only check (expected: either explicit non-nil guarantee, or evidence
GetType()may be nil, confirming this guard is required):#!/bin/bash set -euo pipefail echo "== runtime.Typed contract and GetType() declarations ==" rg -n -C3 --type=go 'type\s+Typed\s+interface|GetType\(\)' bindings/go/runtime echo echo "== Call sites that dereference GetType() in setup path ==" rg -n -C2 --type=go 'typed\.GetType\(\)\.GetName\(\)|typed\.GetType\(\)' cli/cmd/setup/setup.go🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@cli/cmd/setup/setup.go` around lines 117 - 124, The anonymous credential plugin factory currently dereferences typed.GetType() without checking it; add a nil guard for typed.GetType() before calling GetName() in the func(_ context.Context, typed runtime.Typed) (credentials.CredentialPlugin, error) block so it returns a clear error when type metadata is missing (e.g., check if typed.GetType() == nil and return fmt.Errorf("no credential plugin found: missing type metadata") or similar), then only call typed.GetType().GetName() to compare against oidc.OIDCPluginType and construct the existing error path that includes the type when present.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@cli/integration/sigstore_integration_test.go`:
- Around line 111-189: The verify-focused subtests ("verify fails with wrong
issuer", "verify fails with wrong identity", "verify with private
infrastructure") are relying on the earlier "sign and verify" side-effect;
modify each of those tests to create and/or sign the artifact within the test
itself before running verify: call cmd.New() to run the "sign cv" command with
the same signerSpecPath (or create a fresh signed CTF via createCTFWithComponent
and then sign it), using SetArgs and ExecuteContext with t.Context(), so the
verifyCMD in that test always operates on a deterministically signed artifact
(use the local variables ref/freshRef, cfgPath, signerSpecPath as appropriate).
Ensure each test checks signCMD.ExecuteContext(t.Context()) returns no error
before executing verifyCMD.
---
Duplicate comments:
In `@cli/cmd/setup/setup.go`:
- Around line 117-124: The anonymous credential plugin factory currently
dereferences typed.GetType() without checking it; add a nil guard for
typed.GetType() before calling GetName() in the func(_ context.Context, typed
runtime.Typed) (credentials.CredentialPlugin, error) block so it returns a clear
error when type metadata is missing (e.g., check if typed.GetType() == nil and
return fmt.Errorf("no credential plugin found: missing type metadata") or
similar), then only call typed.GetType().GetName() to compare against
oidc.OIDCPluginType and construct the existing error path that includes the type
when present.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 9f4a8c4d-abf3-4f32-8828-164607c965b0
📒 Files selected for processing (3)
cli/cmd/setup/setup.gocli/integration/sigstore_integration_test.gocli/internal/oidcflow/oidcflow.go
🚧 Files skipped from review as they are similar to previous changes (1)
- cli/internal/oidcflow/oidcflow.go
- Improve error messages in signinghandler/registry.go: replace vague 'no internal plugin registered for type %v' with message that includes registered types for diagnostics; fix typo 'typ' → 'type' in getPlugin - Make verify subtests self-contained by introducing signRef helper that each verify-only subtest calls independently, removing dependency on 'sign and verify' subtest side effect - Fix struct field alignment in sigstoreStack (goimports) - Clarify verify docs: 'Supports config-less verification' with explicit description that no --verifier-spec is required for RSASSA-PSS Signed-off-by: Gerald Morrison (D032990) <gerald.morrison@sap.com>
- Improve error messages in signinghandler/registry.go: replace vague 'no internal plugin registered for type %v' with message that includes registered types for diagnostics; fix typo 'typ' → 'type' in getPlugin - Make verify subtests self-contained by introducing signRef helper that each verify-only subtest calls independently, removing dependency on 'sign and verify' subtest side effect - Fix struct field alignment in sigstoreStack (goimports) - Clarify verify docs: 'Supports config-less verification' with explicit description that no --verifier-spec is required for RSASSA-PSS Signed-off-by: Gerald Morrison (D032990) <gerald.morrison@sap.com>
aa9bf38 to
a6bf024
Compare
- Improve error messages in signinghandler/registry.go: replace vague 'no internal plugin registered for type %v' with message that includes registered types for diagnostics; fix typo 'typ' → 'type' in getPlugin - Make verify subtests self-contained by introducing signRef helper that each verify-only subtest calls independently, removing dependency on 'sign and verify' subtest side effect - Fix struct field alignment in sigstoreStack (goimports) - Clarify verify docs: 'Supports config-less verification' with explicit description that no --verifier-spec is required for RSASSA-PSS Signed-off-by: Gerald Morrison (SAP) <gerald.morrison@sap.com> On-behalf-of: Gerald Morrison (SAP) <gerald.morrison@sap.com>
Signed-off-by: Gerald Morrison (SAP) <gerald.morrison@sap.com>
53533a8 to
e6f1d6e
Compare
frewilhelm
left a comment
There was a problem hiding this comment.
Just some smaller remarks. But the how-to works. Well done! :)
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>
frewilhelm
left a comment
There was a problem hiding this comment.
just found some other instances
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>
## Summary Integrates the sigstore cosign signing handler (#2344) into the OCM CLI: - **Credential plugin registry** (`bindings/go/plugin/manager/registries/credentialplugin`) — generic registry that discovers and resolves `credentials.CredentialPlugin` implementations by their runtime type; plugins self-declare their scheme so callers never need to pre-register types manually - **OIDC credential plugin** (`cli/internal/plugin/builtin/oidc`) — first concrete credential plugin; acquires OIDC identity tokens via interactive browser flow (`authorization-code`) - **OIDC browser flow** (`cli/internal/oidcflow`) — opens browser for interactive OIDC token acquisition, runs local callback server, uses a copy of the sigstore success page, but OCM branded > **Note:** Contains `replace` directives for `bindings/go/sigstore` — expected to fail in CI until PR 1 is merged and tagged. ## Merge order This is **PR 2 of 2** — merge after PR 1 is tagged: 1. #2344 → sigstore handler module (**merge + tag first**) 2. **This PR** → CLI sign/verify commands ## TODO - [ ] Enhance `sigstore-integration.yml` workflow with CLI sigstore integration tests as a single job that reuses the scaffolding environment: spin up scaffolding once, run handler integration tests, then run CLI integration tests (`cli/integration/`) against the same env - [ ] Ensure `--signer-spec` with `SigstoreSigningConfiguration/v1alpha1` correctly threads `signingConfig` to the handler ## Test plan - [ ] Remove `replace` directives, point to published tag - [ ] Manual: `ocm sign component-version --signing-config <config>` triggers browser OIDC flow - [ ] CI: `sigstore-integration.yml` runs handler + CLI E2E tests against scaffolding cluster - [ ] CI: CLI integration tests sign and verify a CTF using `--signer-spec` and `--verifier-spec` with scaffolding OIDC token - [ ] `credentialplugin.Registry` resolves `OIDCIdentityTokenProvider/v1alpha1` to the OIDC plugin - [ ] Token exchange flow resolves subject token from env var, file, or inline value --------- Signed-off-by: Gerald Morrison (SAP) <gerald.morrison@sap.com> Signed-off-by: Gergely Brautigam <182850+Skarlso@users.noreply.github.com> Co-authored-by: Gerald Morrison (SAP) <gerald.morrison@sap.com> Co-authored-by: Gergely Brautigam <182850+Skarlso@users.noreply.github.com> Co-authored-by: Matthias Bruns <github@matthiasbruns.com> 2cd5842
…el#2346) ## Summary Integrates the sigstore cosign signing handler (open-component-model#2344) into the OCM CLI: - **Credential plugin registry** (`bindings/go/plugin/manager/registries/credentialplugin`) — generic registry that discovers and resolves `credentials.CredentialPlugin` implementations by their runtime type; plugins self-declare their scheme so callers never need to pre-register types manually - **OIDC credential plugin** (`cli/internal/plugin/builtin/oidc`) — first concrete credential plugin; acquires OIDC identity tokens via interactive browser flow (`authorization-code`) - **OIDC browser flow** (`cli/internal/oidcflow`) — opens browser for interactive OIDC token acquisition, runs local callback server, uses a copy of the sigstore success page, but OCM branded > **Note:** Contains `replace` directives for `bindings/go/sigstore` — expected to fail in CI until PR 1 is merged and tagged. ## Merge order This is **PR 2 of 2** — merge after PR 1 is tagged: 1. open-component-model#2344 → sigstore handler module (**merge + tag first**) 2. **This PR** → CLI sign/verify commands ## TODO - [ ] Enhance `sigstore-integration.yml` workflow with CLI sigstore integration tests as a single job that reuses the scaffolding environment: spin up scaffolding once, run handler integration tests, then run CLI integration tests (`cli/integration/`) against the same env - [ ] Ensure `--signer-spec` with `SigstoreSigningConfiguration/v1alpha1` correctly threads `signingConfig` to the handler ## Test plan - [ ] Remove `replace` directives, point to published tag - [ ] Manual: `ocm sign component-version --signing-config <config>` triggers browser OIDC flow - [ ] CI: `sigstore-integration.yml` runs handler + CLI E2E tests against scaffolding cluster - [ ] CI: CLI integration tests sign and verify a CTF using `--signer-spec` and `--verifier-spec` with scaffolding OIDC token - [ ] `credentialplugin.Registry` resolves `OIDCIdentityTokenProvider/v1alpha1` to the OIDC plugin - [ ] Token exchange flow resolves subject token from env var, file, or inline value --------- Signed-off-by: Gerald Morrison (SAP) <gerald.morrison@sap.com> Signed-off-by: Gergely Brautigam <182850+Skarlso@users.noreply.github.com> Co-authored-by: Gerald Morrison (SAP) <gerald.morrison@sap.com> Co-authored-by: Gergely Brautigam <182850+Skarlso@users.noreply.github.com> Co-authored-by: Matthias Bruns <github@matthiasbruns.com> On-behalf-of: @SAP <jakob.moeller@sap.com>
Summary
Integrates the sigstore cosign signing handler (#2344) into the OCM CLI:
bindings/go/plugin/manager/registries/credentialplugin) — generic registry that discovers and resolvescredentials.CredentialPluginimplementations by their runtime type; plugins self-declare their scheme so callers never need to pre-register types manuallycli/internal/plugin/builtin/oidc) — first concrete credential plugin; acquires OIDC identity tokens via interactive browser flow (authorization-code)cli/internal/oidcflow) — opens browser for interactive OIDC token acquisition, runs local callback server, uses a copy of the sigstore success page, but OCM brandedMerge order
This is PR 2 of 2 — merge after PR 1 is tagged:
TODO
sigstore-integration.ymlworkflow with CLI sigstore integration tests as a single job that reuses the scaffolding environment: spin up scaffolding once, run handler integration tests, then run CLI integration tests (cli/integration/) against the same env--signer-specwithSigstoreSigningConfiguration/v1alpha1correctly threadssigningConfigto the handlerTest plan
replacedirectives, point to published tagocm sign component-version --signing-config <config>triggers browser OIDC flowsigstore-integration.ymlruns handler + CLI E2E tests against scaffolding cluster--signer-specand--verifier-specwith scaffolding OIDC tokencredentialplugin.RegistryresolvesOIDCIdentityTokenProvider/v1alpha1to the OIDC plugin