Documentation
¶
Overview ¶
Package identitytoken resolves and acquires the OIDC identity token used for keyless skill push signing (RFC THV-0080 / #6307). It is CLI-side only: the server never handles credentials, only the already-acquired token forwarded in the push request (skills.PushOptions.IdentityToken).
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ErrNoCredential = errors.New("signing required: no signing credential available. " +
"Provide --key, --identity-token, run in CI with id-token: write permission, or pass --no-sign to push unsigned")
ErrNoCredential is returned when Acquire exhausts every rung of the ladder without obtaining a signing credential. The message names every remaining option so the failure is actionable from the CLI alone.
Functions ¶
func Acquire ¶
Acquire resolves the identity token to sign a skill push with, trying each rung of the ladder in order:
- An explicit --identity-token is always resolved and forwarded, even alongside --key — the ambiguity is a conflict for the server to reject (skillsvc.validateSigningInputs), never something to silently arbitrate client-side.
- --key or --no-sign with no --identity-token means the user made an explicit signing choice; Acquire returns "" without attempting ambient or interactive acquisition.
- A GitHub Actions ambient OIDC token, when present.
- An interactive browser sign-in, gated by opts.Confirm.
- ErrNoCredential.
func Ambient ¶
Ambient fetches a GitHub Actions ambient OIDC token scoped to the sigstore audience. ok is false with a nil error when the environment doesn't carry the id-token: write request variables — that is simply not running under that permission, not a failure. A request that fails once both variables are present IS an error: the caller expected this to work.
func Interactive ¶
func Interactive(tg oauthflow.TokenGetter) (string, error)
Interactive obtains an OIDC identity token via an interactive browser sign-in against the public-good Sigstore OAuth instance. tg is injectable for tests (see oauthflow.StaticTokenGetter); production callers pass oauthflow.DefaultIDTokenGetter.
This blocks until the user completes or abandons the browser flow. oauthflow.OIDConnect accepts no context and hardcodes context.Background() internally, so there is no cancellation path to plumb here: the redirect wait self-limits to 120s, but provider discovery, the code exchange, and the out-of-band stdin fallback are all unbounded. That's acceptable because this only runs after an explicit y/N confirmation on a TTY — a human is already present, and Ctrl-C is the exit. Wrapping this in a goroutine would leak one blocked on stdin or a listening socket with no way to cancel it, which is worse than an unbounded wait a human can interrupt themselves.
func Resolve ¶
Resolve interprets the --identity-token flag value: a path to a file containing the token, or the raw token itself (cosign parity with --key, which already accepts a path). An existing regular file wins; otherwise a JWT-shaped value (two dots) is used as a literal token; otherwise this is an error rather than a guess, so a mistyped path is never silently forwarded to Fulcio as if it were a token.
Types ¶
type Options ¶
type Options struct {
// FlagValue is the raw --identity-token flag value, if given.
FlagValue string
// Key is the --key flag value, if given.
Key string
// NoSign is the --no-sign flag value.
NoSign bool
// Confirm is called only when no token was found ambiently, to ask the
// user (via the CLI's own TTY-gated prompt) whether to open a browser
// for an interactive sign-in. Returning (false, nil) declines or skips
// without error. Required.
Confirm func() (bool, error)
}
Options configures Acquire.