diff --git a/README.md b/README.md index e8549bb7..10bd3ee4 100644 --- a/README.md +++ b/README.md @@ -80,7 +80,7 @@ The following config options are supported: | redirectURL | | OIDC Redirect URL | | rekor | https://rekor.sigstore.dev | Address of Rekor server | | connectorID | | Optional Connector ID to auto-select to pre-select auth flow to use. For the public sigstore instance, valid values are:
- `https://github.com/login/oauth`
- `https://accounts.google.com`
- `https://login.microsoftonline.com` | -| tokenProvider | | Optional OIDC token provider to use to fetch tokens. If not set, any available providers are used. valid values are:
- `interactive`
- `spiffe`
- `google-workload-identity`
- `google-impersonation`
- `github-actions`
- `filesystem`
- `buildkite-agent` | +| tokenProvider | | Optional OIDC token provider to use to fetch tokens. If not set, any available providers are used. valid values are:
- `interactive`
- `device` (OAuth 2.0 device flow — for headless / remote-SSH workflows)
- `spiffe`
- `google-workload-identity`
- `google-impersonation`
- `github-actions`
- `filesystem`
- `buildkite-agent` | | timestampServerURL | | Address of timestamping authority. If set, a trusted timestamp will be included in the signature. | | timestampCertChain | | Path to PEM encoded certificate chain for RFC3161 Timestamp Authority verification. | | autoclose | true | If true, autoclose the browser window after `autocloseTimeout`. In order for autoclose to work you must also set `connectorID`. | @@ -93,7 +93,7 @@ The following config options are supported: | ---------------------------- | ------------------ | -------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | GITSIGN_CREDENTIAL_CACHE | | | Optional path to [gitsign-credential-cache](cmd/gitsign-credential-cache/README.md) socket. | | GITSIGN_CONNECTOR_ID | ✅ | | Optional Connector ID to auto-select to pre-select auth flow to use. For the public sigstore instance, valid values are:
- `https://github.com/login/oauth`
- `https://accounts.google.com`
- `https://login.microsoftonline.com` | -| GITSIGN_TOKEN_PROVIDER | ✅ | | Optional OIDC token provider to use to fetch tokens. If not set, any available providers are used. valid values are:
- `interactive`
- `spiffe`
- `google-workload-identity`
- `google-impersonation`
- `github-actions`
- `filesystem`
- `buildkite-agent` | +| GITSIGN_TOKEN_PROVIDER | ✅ | | Optional OIDC token provider to use to fetch tokens. If not set, any available providers are used. valid values are:
- `interactive`
- `device` (OAuth 2.0 device flow — for headless / remote-SSH workflows)
- `spiffe`
- `google-workload-identity`
- `google-impersonation`
- `github-actions`
- `filesystem`
- `buildkite-agent` | | GITSIGN_FULCIO_URL | ✅ | https://fulcio.sigstore.dev | Address of Fulcio server | | GITSIGN_LOG | ❌ | | Path to log status output. Helpful for debugging when no TTY is available in the environment. | | GITSIGN_OIDC_CLIENT_ID | ✅ | sigstore | OIDC client ID for application diff --git a/internal/config/config.go b/internal/config/config.go index bc6149da..bd8c6881 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -77,7 +77,12 @@ type Config struct { ConnectorID string // TokenProviders select a OIDC token provider to use to fetch tokens. If not set, all providers are attempted. // See https://github.com/sigstore/cosign/tree/main/pkg/providers for more details. - // Valid values are: [interactive, spiffe, google-workload-identity, google-impersonation, github-actions, filesystem, buildkite-agent] + // Valid values are: [interactive, device, spiffe, google-workload-identity, google-impersonation, github-actions, filesystem, buildkite-agent] + // + // "device" runs the OAuth 2.0 device authorization grant (RFC 8628) against + // the configured Issuer — the user opens the printed verification URL on any + // browser to complete consent; the SSH session never needs a browser or + // port forward. Intended for headless / remote-SSH developer workflows. TokenProvider string // Timestamp Authority address to use to get a trusted timestamp diff --git a/internal/fulcio/identity.go b/internal/fulcio/identity.go index ba28505c..cc33723f 100644 --- a/internal/fulcio/identity.go +++ b/internal/fulcio/identity.go @@ -235,10 +235,20 @@ func (f *IdentityFactory) NewIdentity(ctx context.Context, cfg *config.Config) ( // If enabled, try OIDC token providers to get a token. unless the token provider is "interactive" (in which case always do default interactive flow). var provider providers.Interface - if cfg.TokenProvider == "" && providers.Enabled(ctx) { + switch { + case cfg.TokenProvider == "" && providers.Enabled(ctx): // If no token provider is set, look for any available provider to use. provider = defaultFlowProvider{} - } else if cfg.TokenProvider != "" && cfg.TokenProvider != "interactive" { + case cfg.TokenProvider == "device": + // Special-case: use the OAuth 2.0 device authorization grant (RFC 8628) + // directly via the sigstore oauthflow package. The user opens the + // printed verification URL on any browser (phone, laptop, anywhere) to + // complete OAuth consent; the SSH session itself never needs a browser, + // port forward, or localhost callback. Useful on remote/headless dev + // hosts where the interactive flow can't open a browser locally. + fmt.Fprintln(f.out, "using device authorization flow") // nolint:errcheck + authFlow = oauthflow.NewDeviceFlowTokenGetterForIssuer(cfg.Issuer) + case cfg.TokenProvider != "" && cfg.TokenProvider != "interactive": fmt.Fprintln(f.out, "using token provider", cfg.TokenProvider) // nolint:errcheck // If a token provider is explicitly set always use it, unless it's "interactive",