Skip to content

feat(cli): integrate cosign signing handler [2/2]#2346

Merged
morri-son merged 80 commits into
open-component-model:mainfrom
morri-son:feat/cosign-signing-handler-3-cli
May 20, 2026
Merged

feat(cli): integrate cosign signing handler [2/2]#2346
morri-son merged 80 commits into
open-component-model:mainfrom
morri-son:feat/cosign-signing-handler-3-cli

Conversation

@morri-son

@morri-son morri-son commented Apr 20, 2026

Copy link
Copy Markdown
Contributor

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. feat(sigstore): add cosign signing handler [1/2] #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

@morri-son morri-son requested a review from a team as a code owner April 20, 2026 11:57
@morri-son morri-son added the kind/feature new feature, enhancement, improvement, extension label Apr 20, 2026
@netlify

netlify Bot commented Apr 20, 2026

Copy link
Copy Markdown

Deploy Preview for ocm-website ready!

Name Link
🔨 Latest commit 93c91f2
🔍 Latest deploy log https://app.netlify.com/projects/ocm-website/deploys/6a0d73fb28a6250008ae328c
😎 Deploy Preview https://deploy-preview-2346--ocm-website.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai

coderabbitai Bot commented Apr 20, 2026

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It 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 reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds 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.

Changes

Sigstore keyless signing flow (single cohesive DAG)

Layer / File(s) Summary
Public types & defaults
cli/internal/oidcflow/oidcflow.go
Adds Token, Options, and default issuer/client ID constants and timeouts used by the OIDC interactive flow.
Core OIDC flow implementation
cli/internal/oidcflow/oidcflow.go
Implements PKCE S256 auth-code flow with loopback HTTP callback, state/nonce generation, browser launch, token exchange, id_token verification, and helper functions (PKCE, randomString, openBrowser, successHTML).
OIDC flow unit tests
cli/internal/oidcflow/oidcflow_test.go
Comprehensive tests for PKCE derivation, callback handler behaviors (state, issuer, errors, methods), wait/timeouts, browser opener, and options/defaults.
Credential plugin API & parsing
cli/internal/plugin/builtin/oidc/oidc_plugin.go
Adds OIDC plugin type/version constants, OIDCPlugin with GetConsumerIdentity (parse issuer/clientID with defaults) and Resolve (runs interactive flow and returns token).
OIDC plugin tests
cli/internal/plugin/builtin/oidc/oidc_plugin_test.go
Tests GetConsumerIdentity and defaulting behavior.
Plugin registration
cli/internal/plugin/builtin/oidc/register.go, cli/internal/plugin/builtin/builtin.go
Registers the OIDC/Sigstore signing handler in the builtin registry and wires registration into builtin plugin setup (error wraps on failure).
CLI wiring & setup provider
cli/cmd/setup/setup.go, cli/cmd/cmd_test.go
Supply a concrete OIDC credential plugin provider at setup time; test updated to exercise signer/verifier YAML usage.
CLI help & docs
cli/cmd/sign/component-version/cmd.go, cli/cmd/verify/component-version/cmd.go, cli/docs/reference/ocm_sign_component-version.md, cli/docs/reference/ocm_verify_component-version.md
Extend command help and docs to document --signer-spec/--verifier-spec for Sigstore keyless types, add YAML examples, and explain identity/issuer constraints and endpoint discovery.
Integration test + Taskfile
cli/integration/sigstore_integration_test.go, cli/integration/Taskfile.yml
Add end-to-end Sigstore CLI integration test exercising sign/verify scenarios and a Taskfile task/env var for running sigstore integrations.
Dependency updates
cli/go.mod, cli/integration/go.mod
Add github.com/coreos/go-oidc/v3, add/local-replace for bindings/go/sigstore, and bump various ocm bindings and transitive modules.
Minor test import change
cli/integration/download_resource_integration_test.go
Reordered helmblob import only; no logic change.

Sequence Diagram

sequenceDiagram
    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
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Suggested reviewers

  • frewilhelm
  • fabianburth
  • Skarlso
  • jakobmoellerdev

Poem

🐰 I hopped to open a browser door,

PKCE and nonce in a nimble soar,
Tokens fetched and signatures hum,
Rekor & Fulcio beat their drum,
A rabbit cheers — secure signing once more.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 5.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat(cli): integrate cosign signing handler [2/2]' clearly and specifically describes the main change: integration of the cosign signing handler into the CLI as part two of a two-part series.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The PR description clearly outlines the integration of sigstore cosign signing handler into the OCM CLI with specific component details, objectives, and merge dependencies.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions Bot added the size/l Large label Apr 20, 2026

@fabianburth fabianburth left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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?

Comment thread cli/internal/plugin/builtin/oidc/oidc_plugin.go Outdated
Comment thread cli/internal/plugin/builtin/sigstore/oidc_plugin.go Outdated
Comment thread cli/internal/plugin/builtin/cosign/oidc_plugin.go Outdated
Comment thread cli/internal/plugin/builtin/sigstore/oidc_plugin.go Outdated
Comment thread cli/cmd/setup/setup.go Outdated
Comment thread cli/internal/oidcflow/oidcflow.go Outdated
Comment thread cli/internal/oidcflow/oidcflow.go
Comment thread cli/internal/plugin/builtin/oidc/oidc_plugin.go
Comment thread cli/internal/plugin/builtin/builtin.go
Comment thread tools/mcp-knowledge-server/testdata/bindings/go/blob/doc.go Outdated
@morri-son morri-son force-pushed the feat/cosign-signing-handler-3-cli branch 2 times, most recently from 59448c2 to 7bb54e3 Compare April 22, 2026 17:36
@morri-son morri-son changed the title feat(cli): integrate cosign signing handler [3/3] feat(cli): integrate cosign signing handler [2/2] Apr 24, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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 referencing oidcflow.DefaultIssuer and oidcflow.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 the newPKCE constructor.

This test manually constructs a pkce struct and validates its methods, but doesn't test newPKCE() which includes the provider claims check and verifier generation. Consider adding a test that exercises newPKCE with 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

📥 Commits

Reviewing files that changed from the base of the PR and between 6c826cf and 5eb9a5d.

⛔ Files ignored due to path filters (2)
  • cli/go.sum is excluded by !**/*.sum
  • cli/integration/go.sum is excluded by !**/*.sum
📒 Files selected for processing (15)
  • cli/cmd/cmd_test.go
  • cli/cmd/setup/setup.go
  • cli/cmd/sign/component-version/cmd.go
  • cli/cmd/verify/component-version/cmd.go
  • cli/docs/reference/ocm_sign_component-version.md
  • cli/docs/reference/ocm_verify_component-version.md
  • cli/go.mod
  • cli/integration/download_resource_integration_test.go
  • cli/integration/go.mod
  • cli/internal/oidcflow/oidcflow.go
  • cli/internal/oidcflow/oidcflow_test.go
  • cli/internal/plugin/builtin/builtin.go
  • cli/internal/plugin/builtin/oidc/oidc_plugin.go
  • cli/internal/plugin/builtin/oidc/oidc_plugin_test.go
  • cli/internal/plugin/builtin/oidc/register.go

Comment thread cli/cmd/setup/setup.go Outdated
Comment thread cli/docs/reference/ocm_sign_component-version.md Outdated
Comment thread cli/internal/oidcflow/oidcflow.go Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
cli/integration/Taskfile.yml (1)

20-20: Quote SIGSTORE_ENV_FILE in 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

📥 Commits

Reviewing files that changed from the base of the PR and between 5eb9a5d and 279ce77.

📒 Files selected for processing (3)
  • cli/integration/Taskfile.yml
  • cli/integration/sigstore_integration_test.go
  • cli/internal/oidcflow/oidcflow_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • cli/internal/oidcflow/oidcflow_test.go

Comment thread cli/integration/sigstore_integration_test.go Outdated
@github-actions github-actions Bot added the area/documentation Documentation related label Apr 29, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 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 path

The test at line 245 manually assembles URL query parameters, whereas the production code at oidcflow.go:128-132 calls oauth2.Config.AuthCodeURL() with options from p.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: call cfg.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

📥 Commits

Reviewing files that changed from the base of the PR and between 279ce77 and c41bbd9.

📒 Files selected for processing (3)
  • cli/internal/oidcflow/oidcflow.go
  • cli/internal/oidcflow/oidcflow_test.go
  • docs/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

@morri-son

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Apr 30, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
cli/cmd/setup/setup.go (1)

117-124: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Add a typed.GetType() == nil guard before dereference.

At Line 121, typed.GetType().GetName() can panic when typed is 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

📥 Commits

Reviewing files that changed from the base of the PR and between c41bbd9 and 9ae4ced.

📒 Files selected for processing (3)
  • cli/cmd/setup/setup.go
  • cli/integration/sigstore_integration_test.go
  • cli/internal/oidcflow/oidcflow.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • cli/internal/oidcflow/oidcflow.go

Comment thread cli/integration/sigstore_integration_test.go Outdated
Comment thread cli/internal/oidcflow/oidcflow.go
Comment thread bindings/go/plugin/manager/registries/signinghandler/registry.go Outdated
Comment thread cli/cmd/cmd_test.go Outdated
Comment thread cli/docs/reference/ocm_verify_component-version.md
Comment thread cli/integration/sigstore_integration_test.go Outdated
morri-son pushed a commit to morri-son/open-component-model that referenced this pull request May 10, 2026
- 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>
@morri-son morri-son requested a review from matthiasbruns May 11, 2026 08:31
morri-son pushed a commit to morri-son/open-component-model that referenced this pull request May 11, 2026
- 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>
@morri-son morri-son force-pushed the feat/cosign-signing-handler-3-cli branch from aa9bf38 to a6bf024 Compare May 11, 2026 08:31
morri-son pushed a commit to morri-son/open-component-model that referenced this pull request May 12, 2026
- 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>
@morri-son morri-son force-pushed the feat/cosign-signing-handler-3-cli branch from 53533a8 to e6f1d6e Compare May 19, 2026 15:24

@frewilhelm frewilhelm left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Just some smaller remarks. But the how-to works. Well done! :)

Comment thread website/content/docs/how-to/Sign and Verify/sign-component-version.md Outdated
Comment thread website/content/docs/how-to/Sign and Verify/sign-component-version.md Outdated
Comment thread website/content/docs/how-to/Sign and Verify/verify-component-version.md Outdated
Comment thread website/content/docs/how-to/Sign and Verify/verify-component-version.md Outdated
Comment thread website/content/docs/how-to/Sign and Verify/verify-component-version.md Outdated
Signed-off-by: Gerald Morrison (SAP) <gerald.morrison@sap.com>
Signed-off-by: Gerald Morrison (SAP) <gerald.morrison@sap.com>

@frewilhelm frewilhelm left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The very last nits

Comment thread website/content/docs/how-to/Sign and Verify/verify-component-version.md Outdated
Comment thread website/content/docs/how-to/Sign and Verify/verify-component-version.md Outdated
Comment thread website/content/docs/how-to/Sign and Verify/sign-component-version.md Outdated
morrison-sap and others added 2 commits May 20, 2026 09:41
Signed-off-by: Gerald Morrison (SAP) <gerald.morrison@sap.com>

@frewilhelm frewilhelm left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

just found some other instances

Comment thread website/content/docs/how-to/Sign and Verify/verify-component-version.md Outdated
Comment thread website/content/docs/how-to/Sign and Verify/verify-component-version.md Outdated
Comment thread website/content/docs/how-to/Sign and Verify/verify-component-version.md Outdated
Signed-off-by: Gerald Morrison (SAP) <gerald.morrison@sap.com>
Signed-off-by: Gerald Morrison (SAP) <gerald.morrison@sap.com>
@morri-son morri-son requested a review from frewilhelm May 20, 2026 08:06
matthiasbruns
matthiasbruns previously approved these changes May 20, 2026

@matthiasbruns matthiasbruns left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If you nee

Signed-off-by: Gerald Morrison (SAP) <gerald.morrison@sap.com>
Signed-off-by: Gerald Morrison (SAP) <gerald.morrison@sap.com>
@morri-son morri-son requested a review from matthiasbruns May 20, 2026 08:42
@morri-son morri-son merged commit 2cd5842 into open-component-model:main May 20, 2026
38 checks passed
ocmbot Bot pushed a commit that referenced this pull request May 20, 2026
## 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
jakobmoellerdev pushed a commit to jakobmoellerdev/open-component-model that referenced this pull request May 20, 2026
…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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/documentation Documentation related component/github-actions Changes on GitHub Actions or within `.github/` directory kind/feature new feature, enhancement, improvement, extension size/l Large

Projects

None yet

Development

Successfully merging this pull request may close these issues.

docs: Enhance how-tos and add tutorial for signing and verification with Sigstore Wire sigstore handler and OIDC credential plugin into the OCM CLI

7 participants