oidc

package
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 20, 2026 License: Apache-2.0 Imports: 15 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ExampleConfig

func ExampleConfig() string

ExampleConfig returns an example configuration file content for documentation.

func ValidateProvidersConfig

func ValidateProvidersConfig(ctx context.Context, config *ProvidersConfig) error

ValidateProvidersConfig checks if a providers configuration is valid. This can be used to validate configuration files before deployment.

Types

type BaseProvider

type BaseProvider struct {
	// contains filtered or unexported fields
}

BaseProvider provides common OIDC verification functionality. Provider implementations can embed this to avoid duplicating verification logic.

SECURITY: Includes JWKS refresh mechanism to handle provider key rotation. If provider keys are compromised and rotated, the authority refreshes JWKS every hour instead of caching indefinitely.

func NewBaseProvider

func NewBaseProvider(ctx context.Context, config ProviderConfig) (*BaseProvider, error)

NewBaseProvider creates a new base provider with common OIDC verification setup. SECURITY FIX #6: Starts JWKS refresh goroutine to handle provider key rotation. RESOURCE MANAGEMENT: Uses cancellable context to ensure HTTP requests stop on shutdown.

func (*BaseProvider) Config

func (b *BaseProvider) Config() ProviderConfig

Config returns the provider's configuration.

func (*BaseProvider) Stop

func (b *BaseProvider) Stop()

Stop stops the JWKS refresh goroutine. Should be called when shutting down the provider to avoid goroutine leaks. RESOURCE MANAGEMENT: Cancels context to stop in-flight HTTP requests immediately.

func (*BaseProvider) ValidateConfig

func (b *BaseProvider) ValidateConfig() error

ValidateConfig checks if the base provider configuration is valid.

func (*BaseProvider) VerifyTokenInternal

func (b *BaseProvider) VerifyTokenInternal(ctx context.Context, rawToken string) (*oidc.IDToken, error)

VerifyTokenInternal handles common OIDC token verification. Provider implementations call this and then extract provider-specific claims. SECURITY: Uses read lock to allow concurrent verification during JWKS refresh.

type Claims

type Claims struct {
	// Standard OIDC claims
	Subject   string    `json:"sub"`           // Subject identifier (user/service ID)
	Issuer    string    `json:"iss"`           // Token issuer URL
	Audience  []string  `json:"aud"`           // Intended audience(s)
	ExpiresAt time.Time `json:"exp"`           // Token expiration time
	IssuedAt  time.Time `json:"iat"`           // Token issuance time
	NotBefore time.Time `json:"nbf,omitempty"` // Token validity start time

	// Provider-specific claims (stored as map for flexibility)
	// Examples:
	//   GitHub Actions: "repository", "ref", "workflow", "actor", "sha"
	//   GitLab CI: "project_path", "pipeline_source", "ref", "runner_id"
	//   AWS: "arn", "account", "assumed_role", "session_name"
	Extra map[string]interface{} `json:"extra"`
}

Claims represents normalized claims extracted from an OIDC token. Providers map their specific claim structure to this common format.

type CloudflareAccessClaims

type CloudflareAccessClaims struct {
	// Email is the authenticated user's email address.
	Email string `json:"email"`

	// Sub is the subject identifier (user ID within CF Access).
	Sub string `json:"sub"`

	// IdentityNonce is a unique nonce per authentication session.
	IdentityNonce string `json:"identity_nonce"`
}

CloudflareAccessClaims represents Cloudflare Access-specific OIDC token claims.

type CloudflareAccessConfig

type CloudflareAccessConfig struct {
	ProviderConfig

	// TeamDomain is the Cloudflare Access team name (e.g., "myteam").
	// Used to construct the issuer URL: https://<TeamDomain>.cloudflareaccess.com
	TeamDomain string `json:"team_domain" yaml:"team_domain"`

	// AllowedEmails restricts which email addresses can get bridge certificates.
	// Empty list = allow all authenticated emails.
	AllowedEmails []string `json:"allowed_emails" yaml:"allowed_emails"`

	// CapabilityDomain is the domain used in capability URIs.
	// Default: uses the TeamDomain value.
	// Example: "rosary.bot" → urn:signet:cap:mcp:rosary.bot/<email>
	CapabilityDomain string `json:"capability_domain,omitempty" yaml:"capability_domain,omitempty"`
}

CloudflareAccessConfig extends ProviderConfig with Cloudflare Access-specific settings.

type CloudflareAccessProvider

type CloudflareAccessProvider struct {
	*BaseProvider
	// contains filtered or unexported fields
}

CloudflareAccessProvider implements the Provider interface for Cloudflare Access JWTs. Cloudflare Access issues OIDC tokens for authenticated users via Access policies.

Token claims reference: https://developers.cloudflare.com/cloudflare-one/identity/authorization-cookie/application-token/

func NewCloudflareAccessProvider

func NewCloudflareAccessProvider(ctx context.Context, config CloudflareAccessConfig) (*CloudflareAccessProvider, error)

NewCloudflareAccessProvider creates a new Cloudflare Access OIDC provider.

func (*CloudflareAccessProvider) MapCapabilities

func (p *CloudflareAccessProvider) MapCapabilities(claims *Claims) ([]string, error)

MapCapabilities converts Cloudflare Access claims into Signet capability URIs. Maps email to: urn:signet:cap:mcp:rosary.bot/<email>

SECURITY: Validates email format and URL-escapes to prevent injection.

func (*CloudflareAccessProvider) Name

func (p *CloudflareAccessProvider) Name() string

Name returns the provider's unique identifier.

func (*CloudflareAccessProvider) ValidateConfig

func (p *CloudflareAccessProvider) ValidateConfig() error

ValidateConfig checks if the Cloudflare Access provider configuration is valid.

func (*CloudflareAccessProvider) Verify

func (p *CloudflareAccessProvider) Verify(ctx context.Context, rawToken string) (*Claims, error)

Verify validates a Cloudflare Access OIDC token and returns normalized claims.

type GitHubActionsClaims

type GitHubActionsClaims struct {
	// Repository is the owner/repo (e.g., "agentic-research/signet")
	Repository string `json:"repository"`

	// Ref is the git ref that triggered the workflow (e.g., "refs/heads/main")
	Ref string `json:"ref"`

	// SHA is the commit SHA that triggered the workflow
	SHA string `json:"sha"`

	// Workflow is the workflow file path (e.g., ".github/workflows/release.yml")
	Workflow string `json:"workflow"`

	// Actor is the GitHub username that triggered the workflow
	Actor string `json:"actor"`

	// JobWorkflowRef is the full ref including workflow file
	// Format: "owner/repo/.github/workflows/file.yml@refs/heads/main"
	JobWorkflowRef string `json:"job_workflow_ref"`

	// RepositoryOwner is the repository owner (e.g., "agentic-research")
	RepositoryOwner string `json:"repository_owner"`

	// RepositoryOwnerID is the owner's numeric GitHub ID
	RepositoryOwnerID string `json:"repository_owner_id"`

	// RunID is the unique workflow run ID
	RunID string `json:"run_id"`

	// RunNumber is the workflow run number
	RunNumber string `json:"run_number"`

	// RunAttempt is the attempt number for this run (for re-runs)
	RunAttempt string `json:"run_attempt"`

	// JTI is the unique token identifier for replay prevention.
	// If not present in the raw JWT, synthesized from run_id + run_attempt.
	JTI string `json:"jti"`
}

GitHubActionsClaims represents GitHub Actions-specific OIDC token claims. Reference: https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect#understanding-the-oidc-token

func GetGitHubClaims

func GetGitHubClaims(claims *Claims) (*GitHubActionsClaims, error)

GetGitHubClaims is a helper to extract typed GitHub claims from normalized Claims. This is useful when the authority needs access to GitHub-specific information.

type GitHubActionsConfig

type GitHubActionsConfig struct {
	ProviderConfig

	// AllowedRepositories restricts which repositories can get bridge certificates.
	// Empty list = allow all repositories. Useful for self-hosted authority servers
	// that only serve specific organizations/repositories.
	// Format: "owner/repo" (e.g., "agentic-research/signet")
	AllowedRepositories []string `json:"allowed_repositories" yaml:"allowed_repositories"`

	// AllowedWorkflows restricts which workflow files can get bridge certificates.
	// Empty list = allow all workflows.
	// Format: relative path (e.g., ".github/workflows/release.yml")
	AllowedWorkflows []string `json:"allowed_workflows" yaml:"allowed_workflows"`

	// RequireRefProtection requires the ref to be a protected branch or tag.
	// Prevents bridge certificates from being issued for PRs from forks.
	// When enabled, only refs matching refs/heads/* and refs/tags/* are allowed;
	// refs matching refs/pull/* are explicitly denied.
	RequireRefProtection bool `json:"require_ref_protection" yaml:"require_ref_protection"`

	// ProtectedBranches restricts which branches are allowed when RequireRefProtection is enabled.
	// If non-empty, only branches whose name (without the refs/heads/ prefix) appears in this
	// list are permitted. Tags (refs/tags/*) are always allowed regardless of this setting.
	// If empty, all refs/heads/* and refs/tags/* refs are allowed.
	// Example: ["main", "master"]
	ProtectedBranches []string `json:"protected_branches,omitempty" yaml:"protected_branches,omitempty"`
}

GitHubActionsConfig extends ProviderConfig with GitHub-specific settings.

func DefaultGitHubActionsConfig

func DefaultGitHubActionsConfig(audience string) GitHubActionsConfig

DefaultGitHubActionsConfig returns a sensible default configuration for GitHub Actions. Suitable for development and testing.

type GitHubActionsProvider

type GitHubActionsProvider struct {
	*BaseProvider
	// contains filtered or unexported fields
}

GitHubActionsProvider implements the Provider interface for GitHub Actions OIDC tokens. GitHub Actions provides ambient OIDC credentials via ACTIONS_ID_TOKEN_REQUEST_URL and ACTIONS_ID_TOKEN_REQUEST_TOKEN environment variables.

Token claims reference: https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect

func NewGitHubActionsProvider

func NewGitHubActionsProvider(ctx context.Context, config GitHubActionsConfig) (*GitHubActionsProvider, error)

NewGitHubActionsProvider creates a new GitHub Actions OIDC provider.

func (*GitHubActionsProvider) MapCapabilities

func (p *GitHubActionsProvider) MapCapabilities(claims *Claims) ([]string, error)

MapCapabilities converts GitHub Actions claims into Signet capability URIs. Per docs/design/004-bridge-certs.md, capabilities follow the pattern: urn:signet:cap:{action}:{resource}

SECURITY FIX #8: Validates repository format and URL-escapes to prevent injection.

func (*GitHubActionsProvider) Name

func (p *GitHubActionsProvider) Name() string

Name returns the provider's unique identifier.

func (*GitHubActionsProvider) ValidateConfig

func (p *GitHubActionsProvider) ValidateConfig() error

ValidateConfig checks if the GitHub Actions provider configuration is valid.

func (*GitHubActionsProvider) Verify

func (p *GitHubActionsProvider) Verify(ctx context.Context, rawToken string) (*Claims, error)

Verify validates a GitHub Actions OIDC token and returns normalized claims.

type Provider

type Provider interface {
	// Name returns the provider's unique identifier (e.g., "github-actions", "gitlab-ci")
	Name() string

	// Verify validates an OIDC token from this provider and returns standard claims.
	// Returns an error if the token is invalid, expired, or from wrong issuer.
	Verify(ctx context.Context, rawToken string) (*Claims, error)

	// MapCapabilities converts provider-specific claims into Signet capability URIs.
	// For example, GitHub's "repository" claim → "urn:signet:cap:write:repo:github.com/{repo}"
	MapCapabilities(claims *Claims) ([]string, error)

	// ValidateConfig checks if the provider's configuration is valid.
	// Called during initialization to fail fast on misconfiguration.
	ValidateConfig() error
}

Provider represents an OIDC identity provider that can issue bridge certificates. Implementations handle provider-specific token verification, claim extraction, and capability mapping for different platforms (GitHub Actions, GitLab CI, AWS, etc.)

type ProviderConfig

type ProviderConfig struct {
	// Name uniquely identifies this provider (e.g., "github-actions")
	Name string `json:"name" yaml:"name"`

	// IssuerURL is the OIDC discovery endpoint (e.g., "https://token.actions.githubusercontent.com")
	IssuerURL string `json:"issuer_url" yaml:"issuer_url"`

	// Audience is the expected "aud" claim value (typically the authority's URL)
	Audience string `json:"audience" yaml:"audience"`

	// CertificateValidity is the duration for bridge certificates issued for this provider.
	// Default: 5 minutes (per 004-bridge-certs.md design)
	CertificateValidity time.Duration `json:"certificate_validity" yaml:"certificate_validity"`

	// Enabled controls whether this provider is active.
	// Useful for disabling providers without removing config.
	Enabled bool `json:"enabled" yaml:"enabled"`
}

ProviderConfig represents configuration for an OIDC provider. Each provider implementation can embed this and add provider-specific fields.

type ProviderConfigEntry

type ProviderConfigEntry struct {
	// Type specifies the provider implementation (e.g., "github-actions", "gitlab-ci")
	Type string `json:"type" yaml:"type"`

	// Config contains the provider-specific configuration.
	// The structure depends on the Type field.
	Config json.RawMessage `json:"config" yaml:"config"`
}

ProviderConfigEntry represents a single provider's configuration. The Type field determines which provider implementation to instantiate.

type ProvidersConfig

type ProvidersConfig struct {
	// Providers is a list of provider configurations.
	// Each provider has a "type" field that determines which implementation to use.
	Providers []ProviderConfigEntry `json:"providers" yaml:"providers"`
}

ProvidersConfig represents the top-level configuration for OIDC providers. This can be loaded from YAML or JSON files.

type Registry

type Registry struct {
	// contains filtered or unexported fields
}

Registry manages multiple OIDC providers and routes tokens to the correct provider. Enables supporting multiple identity platforms simultaneously (GitHub + GitLab + AWS).

func LoadProvidersFromConfig

func LoadProvidersFromConfig(ctx context.Context, config *ProvidersConfig) (*Registry, error)

LoadProvidersFromConfig creates a registry from parsed configuration.

func LoadProvidersFromEnv

func LoadProvidersFromEnv(ctx context.Context) (*Registry, error)

LoadProvidersFromEnv loads provider configurations from environment variables. This is useful for containerized deployments where config files may not be available.

Environment variables:

SIGNET_OIDC_PROVIDERS - JSON-encoded ProvidersConfig
SIGNET_GITHUB_ACTIONS_ENABLED - Enable GitHub Actions provider (default: false)
SIGNET_GITHUB_ACTIONS_AUDIENCE - Audience for GitHub Actions tokens
SIGNET_GITHUB_ACTIONS_ALLOWED_REPOS - Comma-separated list of allowed repositories

func LoadProvidersFromFile

func LoadProvidersFromFile(ctx context.Context, path string) (*Registry, error)

LoadProvidersFromFile loads provider configurations from a YAML or JSON file. The file format is detected automatically based on the file extension.

func NewRegistry

func NewRegistry() *Registry

NewRegistry creates a new empty provider registry.

func (*Registry) Get

func (r *Registry) Get(name string) Provider

Get retrieves a provider by name. Returns nil if the provider is not registered.

func (*Registry) List

func (r *Registry) List() []string

List returns all registered provider names.

func (*Registry) Register

func (r *Registry) Register(provider Provider) error

Register adds a provider to the registry. Returns an error if a provider with the same name already exists.

func (*Registry) Shutdown

func (r *Registry) Shutdown()

Shutdown gracefully stops all registered providers. RESOURCE MANAGEMENT: Stops JWKS refresh goroutines to prevent leaks. Should be called during server shutdown to clean up resources.

func (*Registry) VerifyToken

func (r *Registry) VerifyToken(ctx context.Context, rawToken string) (Provider, *Claims, error)

VerifyToken attempts to verify a token against all registered providers. Returns the provider that successfully verified the token and the extracted claims. This is useful when the caller doesn't know which provider issued the token.

SECURITY: Uses constant-time provider selection to prevent timing attacks. All providers are tried before returning to avoid leaking which providers are configured.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL