Documentation
¶
Index ¶
- Constants
- func ParseNeonEndpointID(host string) (string, error)
- func TokenExchangeStripHeaders(subjectHeader string) []string
- type CredentialSource
- type ExchangedToken
- type GCPDefaultCredentialsSource
- type GCPSecretManagerClient
- type GCPServiceAccountSource
- type GitHubAppSource
- type HeaderResolver
- type NeonResolver
- type ProcessSource
- type RefreshingSource
- type ResolvedHeader
- type SecretsManagerClient
- type TokenExchangeConfig
- type TokenExchangeDeclined
- type TokenExchangeNotFound
- type TokenExchangeResolverConfig
- type TokenExchangeResponse
- type TokenExchangeSource
- func (s *TokenExchangeSource) Exchange(ctx context.Context, subjectToken, actorToken, requestID string) (*TokenExchangeResponse, error)
- func (s *TokenExchangeSource) Invalidate(subjectToken, actorToken string)
- func (s *TokenExchangeSource) Resolve(ctx context.Context, subjectToken, actorToken, requestID string) (string, error)
- func (s *TokenExchangeSource) ResolveToken(ctx context.Context, subjectToken, actorToken, requestID string) (ExchangedToken, error)
- type UpgradeHint
Constants ¶
const DefaultNeonBaseURL = "https://console.neon.tech"
DefaultNeonBaseURL is the production Neon API base URL.
const DefaultProcessTTL = 5 * time.Minute
DefaultProcessTTL is the refresh interval reported when the command output carries no expiry information and no default was configured.
Variables ¶
This section is empty.
Functions ¶
func ParseNeonEndpointID ¶ added in v0.12.0
ParseNeonEndpointID extracts the Neon endpoint ID from a hostname like "ep-cool-darkness-123456.us-east-2.aws.neon.tech". The "-pooler" suffix (connection pooler endpoints) is stripped.
func TokenExchangeStripHeaders ¶ added in v0.27.0
TokenExchangeStripHeaders returns the request headers that a TokenExchangeResolver with the given subject header deletes from the request. The proxy sanitizes them even when a static credential outranks the resolver.
Types ¶
type CredentialSource ¶
CredentialSource fetches a credential value from an external system.
func NewAWSSecretsManagerSource ¶
func NewAWSSecretsManagerSource(secretID, region string) (CredentialSource, error)
NewAWSSecretsManagerSource creates a CredentialSource backed by AWS Secrets Manager.
func NewEnvSource ¶
func NewEnvSource(varName string) CredentialSource
NewEnvSource creates a CredentialSource that reads from an environment variable.
func NewGCPSecretManagerSource ¶ added in v0.8.0
func NewGCPSecretManagerSource(project, secret, version string) (CredentialSource, error)
NewGCPSecretManagerSource creates a CredentialSource backed by GCP Secret Manager. The returned source implements io.Closer to release the underlying gRPC connection.
func NewStaticSource ¶
func NewStaticSource(value string) CredentialSource
NewStaticSource creates a CredentialSource that returns a fixed value.
type ExchangedToken ¶ added in v0.29.0
type ExchangedToken struct {
AccessToken string
Upgrade UpgradeHint
}
ExchangedToken is a token that ResolveToken returns.
type GCPDefaultCredentialsSource ¶ added in v0.33.0
type GCPDefaultCredentialsSource struct {
// contains filtered or unexported fields
}
GCPDefaultCredentialsSource mints OAuth2 access tokens from Google Application Default Credentials (ADC): GOOGLE_APPLICATION_CREDENTIALS, the gcloud well-known file, or the metadata server, which on GKE serves the Kubernetes service account's Workload Identity. The caller configures no key; ADC uses one only when GOOGLE_APPLICATION_CREDENTIALS or the well-known file holds a service account key. With a target service account, the source uses the ADC token to call the IAM Credentials generateAccessToken method and returns the target's token instead. It implements both CredentialSource and RefreshingSource, and is safe for concurrent use.
func NewGCPDefaultCredentialsSource ¶ added in v0.33.0
func NewGCPDefaultCredentialsSource(scopes, targetServiceAccount string) *GCPDefaultCredentialsSource
NewGCPDefaultCredentialsSource creates a credential source backed by Application Default Credentials. scopes is a space-separated list of OAuth scopes; when empty it defaults to the cloud-platform scope. When targetServiceAccount is not empty, Fetch returns a token for that service account, and the ADC principal needs permission to mint it (roles/iam.serviceAccountTokenCreator).
The constructor does no I/O: each Fetch detects ADC, so a metadata server that is not ready yet fails a Fetch that the caller can retry, not the constructor.
func (*GCPDefaultCredentialsSource) Fetch ¶ added in v0.33.0
func (s *GCPDefaultCredentialsSource) Fetch(ctx context.Context) (string, error)
func (*GCPDefaultCredentialsSource) StartupRetryWindow ¶ added in v0.33.0
func (s *GCPDefaultCredentialsSource) StartupRetryWindow() time.Duration
StartupRetryWindow returns how long a caller should keep retrying a failed first Fetch before it gives up.
func (*GCPDefaultCredentialsSource) TTL ¶ added in v0.33.0
func (s *GCPDefaultCredentialsSource) TTL() time.Duration
func (*GCPDefaultCredentialsSource) Type ¶ added in v0.33.0
func (s *GCPDefaultCredentialsSource) Type() string
type GCPSecretManagerClient ¶ added in v0.8.0
type GCPSecretManagerClient interface {
AccessSecretVersion(ctx context.Context, resourceName string) (string, error)
}
GCPSecretManagerClient abstracts the GCP Secret Manager API for testing.
type GCPServiceAccountSource ¶ added in v0.11.0
type GCPServiceAccountSource struct {
// contains filtered or unexported fields
}
GCPServiceAccountSource mints OAuth2 access tokens from a GCP service account key (the JSON file format produced by `gcloud iam service-accounts keys create`). It signs a JWT with the key and exchanges it for an access token at the key's token_uri. It implements both CredentialSource and RefreshingSource.
func NewGCPServiceAccountSource ¶ added in v0.11.0
func NewGCPServiceAccountSource(keyJSON []byte, scopes string) (*GCPServiceAccountSource, error)
NewGCPServiceAccountSource creates a credential source from a service account key JSON. scopes is a space-separated list of OAuth scopes; when empty it defaults to the cloud-platform scope.
func NewGCPServiceAccountSourceFromKeySource ¶ added in v0.11.0
func NewGCPServiceAccountSourceFromKeySource(keySource CredentialSource, scopes string) *GCPServiceAccountSource
NewGCPServiceAccountSourceFromKeySource creates a credential source whose service account key JSON is fetched from another CredentialSource (e.g., GCP Secret Manager) on first use and cached. When the token endpoint rejects an assertion, the cached key is dropped and re-fetched on the next attempt, so key rotation in the backing source is picked up without a restart. Close releases the key source if it implements io.Closer.
func (*GCPServiceAccountSource) Close ¶ added in v0.11.0
func (s *GCPServiceAccountSource) Close() error
Close releases the key source if it implements io.Closer.
func (*GCPServiceAccountSource) Fetch ¶ added in v0.11.0
func (s *GCPServiceAccountSource) Fetch(ctx context.Context) (string, error)
func (*GCPServiceAccountSource) StartupRetryWindow ¶ added in v0.33.1
func (s *GCPServiceAccountSource) StartupRetryWindow() time.Duration
StartupRetryWindow returns the key source's startup retry window, or zero when the key was provided directly.
func (*GCPServiceAccountSource) TTL ¶ added in v0.11.0
func (s *GCPServiceAccountSource) TTL() time.Duration
func (*GCPServiceAccountSource) Type ¶ added in v0.11.0
func (s *GCPServiceAccountSource) Type() string
type GitHubAppSource ¶
type GitHubAppSource struct {
// contains filtered or unexported fields
}
GitHubAppSource generates GitHub App installation access tokens. It implements both CredentialSource and RefreshingSource.
func NewGitHubAppSource ¶
func NewGitHubAppSource(appID, installationID string, privateKeyPEM []byte) (*GitHubAppSource, error)
NewGitHubAppSource creates a credential source that generates GitHub App installation tokens. privateKeyPEM must be a PEM-encoded RSA private key.
func (*GitHubAppSource) Fetch ¶
func (s *GitHubAppSource) Fetch(ctx context.Context) (string, error)
func (*GitHubAppSource) TTL ¶
func (s *GitHubAppSource) TTL() time.Duration
func (*GitHubAppSource) Type ¶
func (s *GitHubAppSource) Type() string
type HeaderResolver ¶ added in v0.27.0
type HeaderResolver func(ctx context.Context, proxyReq, innerReq *http.Request, host string) ([]ResolvedHeader, error)
HeaderResolver resolves headers for one request. Its signature matches proxy.CredentialResolver apart from the result element type.
func TokenExchangeResolver ¶ added in v0.27.0
func TokenExchangeResolver(cfg TokenExchangeResolverConfig) HeaderResolver
TokenExchangeResolver returns a per-request resolver that exchanges the caller's subject for an access token through one shared TokenExchangeSource. When the STS declines, the resolver returns *TokenExchangeDeclined with Invalidate set.
type NeonResolver ¶ added in v0.12.0
type NeonResolver struct {
APIKey CredentialSource // source for the Neon API key; fetched once per source TTL
// Project is an optional Neon project ID. When set, the resolver queries
// this project directly instead of enumerating all projects — required for
// project-scoped API keys, which cannot list projects.
Project string
BaseURL string // defaults to DefaultNeonBaseURL
TTL time.Duration // password cache TTL; defaults to 5 minutes
HTTPClient *http.Client // defaults to a client with a 15s timeout
// contains filtered or unexported fields
}
NeonResolver resolves Postgres passwords for Neon endpoints via the Neon API. It maps an (endpoint hostname, role, database) tuple to a password by locating the project that owns the endpoint and fetching its connection URI. Resolved passwords are cached for TTL; endpoint-to-project/branch mappings are cached until InvalidatePassword drops them (Neon can reassign an endpoint to a different branch).
The zero value is not usable: APIKey must be set. All other fields are optional. NeonResolver is safe for concurrent use.
func (*NeonResolver) Close ¶ added in v0.12.0
func (r *NeonResolver) Close() error
Close cancels any in-flight Neon API calls so the resolver does not hold up a server shutdown waiting out per-call timeouts. It is safe to call more than once. ResolvePassword calls after Close fail fast with a context error. Close implements io.Closer.
func (*NeonResolver) InvalidatePassword ¶ added in v0.12.0
func (r *NeonResolver) InvalidatePassword(host, user, database string)
InvalidatePassword drops the cached password for the given tuple, along with the endpoint's cached project/branch info (Neon can reassign a compute endpoint to a different branch, e.g. on branch reset). Callers invoke this when authentication fails and then retry once; the retry re-discovers the endpoint and fetches fresh credentials.
func (*NeonResolver) ResolvePassword ¶ added in v0.12.0
func (r *NeonResolver) ResolvePassword(ctx context.Context, host, user, database string) (string, error)
ResolvePassword returns the Postgres password for the given role and database on the Neon endpoint identified by host (e.g. "ep-cool-darkness-123456.us-east-2.aws.neon.tech"). Host comparison is case-insensitive since SNI values are case-insensitive.
func (*NeonResolver) Type ¶ added in v0.12.0
func (r *NeonResolver) Type() string
Type returns the resolver type identifier.
type ProcessSource ¶ added in v0.15.0
type ProcessSource struct {
// contains filtered or unexported fields
}
ProcessSource runs a host command and serves its trimmed stdout as the credential value. It is the universal "bring your own backend" source: any helper that prints a credential (keychain CLIs, `pass`, 1Password, corp credential processes) can back a grant without a dedicated Go implementation. It implements both CredentialSource and RefreshingSource.
func NewProcessSource ¶ added in v0.15.0
func NewProcessSource(command string, defaultTTL time.Duration) *ProcessSource
NewProcessSource creates a credential source that runs command with `sh -c` on every fetch. defaultTTL is the refresh interval to report when the command output carries no expiry information.
func (*ProcessSource) Fetch ¶ added in v0.15.0
func (s *ProcessSource) Fetch(ctx context.Context) (string, error)
func (*ProcessSource) TTL ¶ added in v0.15.0
func (s *ProcessSource) TTL() time.Duration
TTL implements RefreshingSource. When the last output carried a credential_process Expiration, TTL is the time until that expiry (clamped at 0; note the refresh loop floors its wait at 30 seconds, so a nearly-expired credential refreshes on that floor, not instantly). Otherwise the configured default interval applies. No safety margin is subtracted here — the refresh loop refreshes at 75% of TTL.
func (*ProcessSource) Type ¶ added in v0.15.0
func (s *ProcessSource) Type() string
type RefreshingSource ¶
type RefreshingSource interface {
CredentialSource
TTL() time.Duration
}
RefreshingSource is a CredentialSource whose values expire and must be re-fetched periodically. TTL returns the duration until the most recently fetched credential expires. Callers use this to schedule background refresh.
type ResolvedHeader ¶ added in v0.27.0
type ResolvedHeader struct {
Name string
Value string
Grant string
Invalidate func()
InvalidateWithStatus func(int)
Upgrade UpgradeHint
}
ResolvedHeader is one header produced by a TokenExchangeResolver. It carries the subset of the proxy package's credential header that a resolver sets.
type SecretsManagerClient ¶
type SecretsManagerClient interface {
GetSecretValue(ctx context.Context, secretID string) (string, error)
}
SecretsManagerClient abstracts the AWS Secrets Manager API for testing.
type TokenExchangeConfig ¶ added in v0.5.0
type TokenExchangeConfig struct {
Endpoint string // STS token endpoint URL
ClientID string // OAuth client ID for client credentials auth
ClientSecret string // OAuth client secret
Resource string // Target resource URI (e.g., "https://api.github.com")
SubjectTokenType string // Subject token type URI (defaults to access_token type)
ActorTokenType string // Actor token type URI (defaults to access_token type)
}
TokenExchangeConfig configures an RFC 8693 token exchange source.
type TokenExchangeDeclined ¶ added in v0.29.0
type TokenExchangeDeclined struct {
Upgrade UpgradeHint
// Invalidate drops the cached decline. TokenExchangeResolver sets it.
Invalidate func()
}
TokenExchangeDeclined reports that the STS issued no token and told the caller to use its configured default credential instead: a 400 invalid_target response that carries gatekeeper_fallback "default".
func (*TokenExchangeDeclined) Error ¶ added in v0.29.0
func (*TokenExchangeDeclined) Error() string
type TokenExchangeNotFound ¶ added in v0.30.0
type TokenExchangeNotFound struct {
Description string
}
TokenExchangeNotFound reports an STS 404: the subject has no credential for the target. Description is the STS error_description when it is at most 200 printable ASCII characters, truncated past that, or "" otherwise.
func (*TokenExchangeNotFound) Error ¶ added in v0.30.0
func (e *TokenExchangeNotFound) Error() string
type TokenExchangeResolverConfig ¶ added in v0.27.0
type TokenExchangeResolverConfig struct {
TokenExchangeConfig
// Source, when set, serves the exchanges so several resolvers share one
// cache. Nil builds a source from TokenExchangeConfig.
Source *TokenExchangeSource
SubjectHeader string
SubjectFrom string
ActorTokenFrom string
BotSubject string
Grant string
Header string
Prefix string
Format string
// ProxyAuth returns the user and password of the request's proxy
// authentication, or empty strings when it has none. Nil means no
// request has proxy authentication.
ProxyAuth func(*http.Request) (user, password string)
// RequestID returns the request ID carried by ctx. Nil means no ID.
RequestID func(context.Context) string
// AuthValue turns an exchanged token into the header value. Nil uses
// the token as is.
AuthValue func(token, prefix, format string) string
}
TokenExchangeResolverConfig configures TokenExchangeResolver.
type TokenExchangeResponse ¶ added in v0.5.0
type TokenExchangeResponse struct {
AccessToken string `json:"access_token"`
IssuedTokenType string `json:"issued_token_type"`
TokenType string `json:"token_type"`
ExpiresIn int `json:"expires_in"`
// Upgrade is the gatekeeper_upgrade extension parameter, if any.
Upgrade UpgradeHint `json:"-"`
}
TokenExchangeResponse is the STS response per RFC 8693 §2.2.1.
type TokenExchangeSource ¶ added in v0.5.0
type TokenExchangeSource struct {
// contains filtered or unexported fields
}
TokenExchangeSource exchanges a subject token for an access token via RFC 8693. It caches tokens per subject with TTL from the STS response, capped at maxTokenTTL.
func NewTokenExchangeSource ¶ added in v0.5.0
func NewTokenExchangeSource(cfg TokenExchangeConfig) *TokenExchangeSource
NewTokenExchangeSource creates a new RFC 8693 token exchange source.
func (*TokenExchangeSource) Exchange ¶ added in v0.5.0
func (s *TokenExchangeSource) Exchange(ctx context.Context, subjectToken, actorToken, requestID string) (*TokenExchangeResponse, error)
Exchange performs an RFC 8693 token exchange for the given subject token. When actorToken is non-empty, it is included as the actor_token parameter. When requestID is non-empty, it is forwarded as X-Request-Id to the STS.
func (*TokenExchangeSource) Invalidate ¶ added in v0.15.0
func (s *TokenExchangeSource) Invalidate(subjectToken, actorToken string)
Invalidate drops the cached token for the given subject and actor, so the next Resolve performs a fresh exchange. Callers invoke it when the destination returns a status that may indicate the backing credential was rotated, re-authorized, or exhausted after the cached token was issued.
Evictions are rate-limited per key (see defaultInvalidateCooldown); calls within the cooldown are no-ops. Invalidate is safe to call when no entry is cached — it still bars any in-flight exchange from caching a result that predates it.
func (*TokenExchangeSource) Resolve ¶ added in v0.5.0
func (s *TokenExchangeSource) Resolve(ctx context.Context, subjectToken, actorToken, requestID string) (string, error)
Resolve returns the access token that ResolveToken returns.
func (*TokenExchangeSource) ResolveToken ¶ added in v0.29.0
func (s *TokenExchangeSource) ResolveToken(ctx context.Context, subjectToken, actorToken, requestID string) (ExchangedToken, error)
ResolveToken returns a credential for the given subject, using the cache when possible. Cache entries live for the STS-advertised expires_in, capped at maxTokenTTL. A decline returns *TokenExchangeDeclined and is cached for maxTokenTTL, so a host whose default is a static credential does not call the STS on every request. Concurrent requests for the same subject are coalesced into a single STS call via singleflight. When actorToken is non-empty, it is forwarded to the STS as the RFC 8693 actor_token parameter and included in the cache key. When requestID is non-empty, it is forwarded as X-Request-Id to the STS for cross-service correlation.
type UpgradeHint ¶ added in v0.29.0
UpgradeHint is the gatekeeper_upgrade extension parameter of an STS response: what the caller could request beyond the credential it got. Each key maps to one or more values.