Documentation
¶
Overview ¶
Package auth handles CLI authentication: the device authorization grant (wallet/agent/passkey), service-account JWT-bearer, credential storage, and silent token refresh.
Index ¶
- Constants
- Variables
- func AccessToken(ctx context.Context, issuer string) (string, error)
- func AccessTokenForAudience(ctx context.Context, issuer, audience string) (string, error)
- func Claims(token string) (map[string]interface{}, error)
- func Delete(issuer string) error
- func GeneratePKCE() (verifier, challenge string)
- func Save(c *Credential) error
- type Credential
- type DeviceAuthResponse
- type ServiceKey
- type TokenResponse
- func MintServiceAccountToken(ctx context.Context, issuer string, k *ServiceKey, audience string) (*TokenResponse, error)
- func PollOnce(ctx context.Context, issuer, deviceCode, verifier string) (*TokenResponse, time.Duration, error)
- func PollUntil(ctx context.Context, issuer, deviceCode, verifier string, interval int, ...) (*TokenResponse, error)
Constants ¶
const ClientID = "privasys-cli"
ClientID is the baked-in public OIDC client identifier for the CLI. The device flow uses no client secret and no redirect URI.
const DefaultScope = "openid email profile offline_access"
DefaultScope requests an id token, profile/email attributes, and a refresh token (offline_access) for silent renewal.
const PlatformAudience = "privasys-platform"
PlatformAudience is the default resource-server audience for the management-service API.
Variables ¶
var ErrNotLoggedIn = errors.New("not authenticated: run `privasys auth login` or `privasys auth activate-service-account`")
ErrNotLoggedIn is returned when no credential exists for an issuer.
Functions ¶
func AccessToken ¶
AccessToken returns a valid access token for the issuer, honoring (in order): PRIVASYS_ACCESS_TOKEN, PRIVASYS_SERVICE_KEY, a stored service account, then a stored user credential (refreshing silently when needed).
func AccessTokenForAudience ¶ added in v0.7.0
AccessTokenForAudience mints an access token bound to a specific audience (e.g. "attestation-server") so the CLI can call that resource server directly. For user sessions it uses the refresh grant with an `audience:` scope (the rotated refresh token keeps the original scope); for service accounts it mints via JWT-bearer. PRIVASYS_ACCESS_TOKEN is returned as-is.
func Claims ¶
Claims decodes (without verifying) the payload of a JWT. Used for `whoami` against the caller's own token; trust comes from the token having been minted into the keychain by a verified flow, not from local re-validation.
func GeneratePKCE ¶
func GeneratePKCE() (verifier, challenge string)
GeneratePKCE returns a random verifier and its S256 challenge.
func Save ¶
func Save(c *Credential) error
Save persists a credential, pushing the long-lived secrets to the keychain when it is available (falling back to the 0600 file otherwise).
Types ¶
type Credential ¶
type Credential struct {
Issuer string `json:"issuer"`
ClientID string `json:"client_id,omitempty"`
Subject string `json:"subject,omitempty"`
Scope string `json:"scope,omitempty"`
AccessToken string `json:"access_token,omitempty"`
IDToken string `json:"id_token,omitempty"`
AccessExpiresAt time.Time `json:"access_expires_at,omitempty"`
// RefreshToken (user flows) — blanked from the file when kept in keychain.
RefreshToken string `json:"refresh_token,omitempty"`
// ServiceKey (Mode D) — the raw service-key JSON, minted on demand.
// Blanked from the file when kept in keychain.
ServiceKey string `json:"service_key,omitempty"`
IsServiceKeyAcc bool `json:"is_service_account,omitempty"`
// contains filtered or unexported fields
}
Credential is the stored authentication state for one issuer.
The long-lived secrets (refresh token, service-account key) are kept in the OS keychain when available; the short-lived access/id tokens and metadata live in a 0600 file. This split keeps the most sensitive material in the keychain while staying under per-item blob limits (e.g. Windows Credential Manager ~2.5KB) that a full JWT bundle would blow past.
func List ¶
func List() ([]*Credential, error)
List returns the stored credentials (without rehydrating keychain secrets).
func Load ¶
func Load(issuer string) (*Credential, error)
Load returns the credential for an issuer, rehydrating secrets from the keychain when they were stored there.
func (*Credential) MarshalJSON ¶
func (c *Credential) MarshalJSON() ([]byte, error)
MarshalJSON/UnmarshalJSON make the unexported keychain flags persist.
func (*Credential) UnmarshalJSON ¶
func (c *Credential) UnmarshalJSON(data []byte) error
type DeviceAuthResponse ¶
type DeviceAuthResponse struct {
DeviceCode string `json:"device_code"`
UserCode string `json:"user_code"`
VerificationURI string `json:"verification_uri"`
VerificationURIComplete string `json:"verification_uri_complete"`
QRPayload string `json:"qr_payload"`
ExpiresIn int `json:"expires_in"`
Interval int `json:"interval"`
Error string `json:"error"`
ErrorDescription string `json:"error_description"`
}
DeviceAuthResponse is the /device_authorization result (RFC 8628 + the Privasys qr_payload extension).
func BeginDevice ¶
func BeginDevice(ctx context.Context, issuer, scope, agentName string) (*DeviceAuthResponse, string, error)
BeginDevice starts a device authorization. The returned verifier must be kept by the caller and presented when polling.
type ServiceKey ¶
type ServiceKey struct {
Type string `json:"type"`
KeyID string `json:"keyId"`
Key string `json:"key"` // RSA-2048 private key, PKCS#1 PEM
UserID string `json:"userId"`
AccountID string `json:"accountId"`
}
ServiceKey is the on-disk service-account key (same shape the IdP issues).
func ParseServiceKey ¶
func ParseServiceKey(data []byte) (*ServiceKey, error)
ParseServiceKey decodes a service-key.json document.
type TokenResponse ¶
type TokenResponse struct {
AccessToken string `json:"access_token"`
RefreshToken string `json:"refresh_token"`
IDToken string `json:"id_token"`
TokenType string `json:"token_type"`
ExpiresIn int `json:"expires_in"`
Scope string `json:"scope"`
Error string `json:"error"`
ErrorDescription string `json:"error_description"`
}
TokenResponse is the /token result for any grant.
func MintServiceAccountToken ¶
func MintServiceAccountToken(ctx context.Context, issuer string, k *ServiceKey, audience string) (*TokenResponse, error)
MintServiceAccountToken exchanges a signed assertion for an access token via the JWT-bearer grant.