token

package
v0.1.4 Latest Latest
Warning

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

Go to latest
Published: May 17, 2026 License: MIT Imports: 23 Imported by: 0

Documentation

Overview

Package token provides JWT claims and token handling for registry authentication.

Index

Constants

View Source
const (
	AuthMethodOAuth       = "oauth"
	AuthMethodAppPassword = "app_password"
)

Auth method constants

Variables

This section is empty.

Functions

func ExtractAccess

func ExtractAccess(tokenString string) []auth.AccessEntry

ExtractAccess parses a JWT token string and extracts the access entries (scopes) Returns nil if not found or token is invalid This does NOT validate the token - it only parses it to extract the claim

func ExtractAuthMethod

func ExtractAuthMethod(tokenString string) string

ExtractAuthMethod parses a JWT token string and extracts the auth_method claim Returns the auth method or empty string if not found or token is invalid This does NOT validate the token - it only parses it to extract the claim

func ExtractSubject

func ExtractSubject(tokenString string) string

ExtractSubject parses a JWT token string and extracts the Subject claim (the user's DID) Returns the subject or empty string if not found or token is invalid This does NOT validate the token - it only parses it to extract the claim

func HasPushScope

func HasPushScope(access []auth.AccessEntry) bool

HasPushScope checks if any access entry contains a "push" action

Types

type AuthErrorResponse

type AuthErrorResponse struct {
	Error    string `json:"error"`
	Message  string `json:"message"`
	LoginURL string `json:"login_url,omitempty"`
}

AuthErrorResponse is returned when authentication fails in a way the credential helper can handle

type Authorizer added in v0.1.4

type Authorizer interface {
	// Authorize is called once per token issuance, after the requester's
	// ATProto credentials have been validated. Returns nil if `access` is
	// allowed, or an error describing the denial reason. The error message
	// surfaces to the OCI client inside the distribution error JSON body.
	//
	// authMethod is one of AuthMethodOAuth or AuthMethodAppPassword and lets
	// the implementation pick the right service-token fetcher when it needs
	// to talk to the hold (e.g. for crew reconciliation).
	Authorize(ctx context.Context, did, authMethod string, access []auth.AccessEntry) error
}

Authorizer gates issuance of registry JWTs at the auth phase. Implementations decide which sub-checks apply based on `access`: crew reconciliation runs for any token request (so first-time CLI users can pull from a private hold), while membership and quota enforcement only apply to non-wildcard push scopes. The Docker spec model is to embed authorization in the JWT and trust it for its short lifetime; this is the single point where those gates run.

type Claims

type Claims struct {
	jwt.RegisteredClaims
	Access     []auth.AccessEntry `json:"access,omitempty"`
	AuthMethod string             `json:"auth_method,omitempty"` // "oauth" or "app_password"
}

Claims represents the JWT claims for registry authentication This follows the Docker Registry token specification

func NewClaims

func NewClaims(subject, issuer, audience string, expiration time.Duration, access []auth.AccessEntry, authMethod string) *Claims

NewClaims creates a new Claims structure with standard fields

type Handler

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

Handler handles /auth/token requests

func NewHandler

func NewHandler(issuer *Issuer, deviceStore *db.DeviceStore) *Handler

NewHandler creates a new token handler

func (*Handler) ServeHTTP

func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP handles the token request

func (*Handler) SetAuthorizer added in v0.1.4

func (h *Handler) SetAuthorizer(authorizer Authorizer)

SetAuthorizer wires the auth-phase gate. When set, every token request runs Authorize after credentials validate; a non-nil error is returned to the client as a 403 (distribution error JSON) and the JWT is not issued.

func (*Handler) SetOAuthSessionValidator

func (h *Handler) SetOAuthSessionValidator(validator OAuthSessionValidator)

SetOAuthSessionValidator sets the OAuth session validator for validating device auth When set, the handler will validate OAuth sessions are usable before issuing tokens for device auth This prevents the flood of errors that occurs when a stale session is discovered during push

func (*Handler) SetPostAuthCallback

func (h *Handler) SetPostAuthCallback(callback PostAuthCallback)

SetPostAuthCallback sets the callback to be invoked after successful Basic Auth authentication This allows AppView to inject business logic without coupling the token package

func (*Handler) SetServiceAuthFetcher added in v0.1.4

func (h *Handler) SetServiceAuthFetcher(fetcher ServiceAuthFetcher)

SetServiceAuthFetcher binds JWT issuance to the AppView↔hold service-auth. When set, the handler pre-mints the service-auth and stamps the JWT's exp from the cached expiry, so both tokens expire concurrently.

type Issuer

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

Issuer handles JWT token creation and signing

func NewIssuer

func NewIssuer(privateKeyPath, issuer, service string, expiration time.Duration) (*Issuer, error)

NewIssuer creates a new JWT issuer

func NewIssuerFromKey

func NewIssuerFromKey(privateKey *rsa.PrivateKey, certDER []byte, issuer, service string, expiration time.Duration) *Issuer

NewIssuerFromKey creates a JWT issuer from pre-loaded key material. certDER is the DER-encoded X.509 certificate for the x5c JWT header.

func (*Issuer) Expiration

func (i *Issuer) Expiration() time.Duration

Expiration returns the token expiration duration

func (*Issuer) Issue

func (i *Issuer) Issue(subject string, access []auth.AccessEntry, authMethod string) (string, error)

Issue creates and signs a new JWT token using the issuer's configured expiration.

func (*Issuer) IssueWithExpiration added in v0.1.4

func (i *Issuer) IssueWithExpiration(subject string, access []auth.AccessEntry, authMethod string, expiration time.Duration) (string, error)

IssueWithExpiration creates and signs a JWT with a per-call expiration. Used when the JWT lifetime is bound to a downstream credential whose lifetime can be slightly less than the issuer's configured default — e.g. the AppView↔hold service-auth, where the cache applies a 10s safety margin against the PDS-granted exp.

func (*Issuer) PublicKey

func (i *Issuer) PublicKey() *rsa.PublicKey

PublicKey returns the public key for token verification

type OAuthSessionValidator

type OAuthSessionValidator interface {
	// ValidateSession checks if OAuth session is usable by attempting to load/refresh it
	// Returns nil if session is valid, error if session is invalid/expired/needs re-auth
	ValidateSession(ctx context.Context, did string) error
}

OAuthSessionValidator validates OAuth sessions before issuing tokens This interface allows the token handler to verify OAuth sessions are usable (not just that they exist) without depending directly on the OAuth implementation.

type PostAuthCallback

type PostAuthCallback func(ctx context.Context, did, handle, pdsEndpoint, accessToken string) error

PostAuthCallback is called after successful Basic Auth authentication. Parameters: ctx, did, handle, pdsEndpoint, accessToken This allows AppView to perform business logic (profile creation, etc.) without coupling the token package to AppView-specific dependencies.

type ServiceAuthFetcher added in v0.1.4

type ServiceAuthFetcher interface {
	// Fetch ensures a service-auth exists for (did, hold derived from did)
	// and returns its expiry. Returns (zero time, nil) when the user has no
	// hold configured — caller falls back to the issuer's default exp.
	Fetch(ctx context.Context, did, authMethod string) (expiresAt time.Time, err error)
}

ServiceAuthFetcher pre-mints the AppView↔hold service-auth at /auth/token time so the registry JWT can be bound to its lifetime. JWT and service-auth then expire concurrently; when Docker hits 401, the next /auth/token call mints both fresh in lockstep.

type TokenResponse

type TokenResponse struct {
	Token       string `json:"token,omitempty"`        // Legacy field
	AccessToken string `json:"access_token,omitempty"` // Standard field
	ExpiresIn   int    `json:"expires_in,omitempty"`
	IssuedAt    string `json:"issued_at,omitempty"`
}

TokenResponse represents the response from /auth/token

Jump to

Keyboard shortcuts

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