Documentation
¶
Overview ¶
Package auth provides authentication and authorization for Wormhole.
The auth package implements team-based authentication using HMAC-SHA256 tokens and role-based access control for multi-user scenarios.
Features ¶
- Team token generation with HMAC-SHA256 signing
- Token validation (signature + expiration)
- Role-based permissions (admin, member, viewer)
- Simple pre-shared token mode for quick setup
- In-memory team management
Token Modes ¶
Two modes are supported:
- HMAC Mode: Tokens are signed with a secret key and include team, role, issued-at, expiration, and a random nonce.
- Simple Mode: Tokens are plain strings compared against a whitelist. All matched tokens get "default" team + "member" role.
Usage ¶
// HMAC mode
a, err := auth.New(auth.Config{
Secret: []byte("your-secret-key-at-least-16-bytes"),
TokenExpiry: 24 * time.Hour,
})
// Generate team token
token, err := a.GenerateTeamToken("team-name", auth.RoleMember)
// Validate token
claims, err := a.ValidateToken(token)
if err != nil {
return err
}
// Check permission
if !auth.HasPermission(claims, auth.PermissionWrite) {
return auth.ErrForbidden
}
// Simple mode
a := auth.NewSimple([]string{"token-abc", "token-xyz"})
claims, err := a.ValidateToken("token-abc") // returns default/member claims.
Index ¶
- Variables
- func DefaultCredentialsPath() string
- func DefaultSQLiteAuditStorePath() string
- func DefaultSQLiteStorePath() string
- func DeleteCredentials(path, server string) error
- func HasPermission(claims *Claims, perm Permission) bool
- func PollDeviceFlow(ctx context.Context, dc *DeviceCode) (string, error)
- func SaveCredentials(path, server, token string, expiresAt time.Time) error
- type AuditEvent
- type AuditEventType
- type AuditLogger
- func (l *AuditLogger) IsEnabled() bool
- func (l *AuditLogger) Log(event AuditEvent)
- func (l *AuditLogger) LogAuthFailure(ip, reason string)
- func (l *AuditLogger) LogAuthSuccess(ip, teamName string, role Role, sessionID, subdomain string)
- func (l *AuditLogger) LogClientConnected(ip, sessionID, subdomain, teamName string, role Role)
- func (l *AuditLogger) LogClientDisconnected(sessionID, subdomain string, duration time.Duration)
- func (l *AuditLogger) LogIPBlocked(ip string, failureCount int)
- func (l *AuditLogger) LogIPUnblocked(ip string, manual bool)
- func (l *AuditLogger) LogP2PEstablished(sessionID, peerAddr string)
- func (l *AuditLogger) LogP2PFallback(sessionID, reason string)
- func (l *AuditLogger) LogTeamTokensRevoked(teamName string)
- func (l *AuditLogger) LogTokenGenerated(teamName string, role Role)
- func (l *AuditLogger) LogTokenRevoked(tokenID, teamName string)
- func (l *AuditLogger) LogTunnelClosed(sessionID, tunnelID, protocol, reason string)
- func (l *AuditLogger) LogTunnelCreated(sessionID, tunnelID, protocol, publicURL string)
- func (l *AuditLogger) SetEnabled(enabled bool)
- func (l *AuditLogger) Store() AuditStore
- type AuditLoggerConfig
- type AuditQuery
- type AuditStore
- type Auth
- func (a *Auth) CleanupRevokedTokens() int
- func (a *Auth) Close() error
- func (a *Auth) ExtendTokenExpiry(token string, extension time.Duration) (string, error)
- func (a *Auth) GenerateTeamToken(teamName string, role Role) (string, error)
- func (a *Auth) GetTeam(name string) (*TeamInfo, error)
- func (a *Auth) IsRevoked(tokenID string) bool
- func (a *Auth) ListTeams() []TeamInfo
- func (a *Auth) RefreshAndRevokeToken(oldToken string) (string, error)
- func (a *Auth) RefreshToken(token string) (string, error)
- func (a *Auth) RegisterTeam(name string) error
- func (a *Auth) RevokeAllTeamTokens(teamName string) error
- func (a *Auth) RevokeToken(tokenID string, expiresAt time.Time) error
- func (a *Auth) RevokeTokenByString(token string) error
- func (a *Auth) RevokedTokenCount() int
- func (a *Auth) SetOIDCValidator(v *OIDCValidator)
- func (a *Auth) Store() Store
- func (a *Auth) UnrevokeToken(tokenID string)
- func (a *Auth) ValidateToken(token string) (*Claims, error)
- type Claims
- type Config
- type Credentials
- type DeviceCode
- type DeviceFlowConfig
- type MemoryAuditStore
- type MemoryStore
- func (s *MemoryStore) CleanupExpiredRevocations() (int, error)
- func (s *MemoryStore) Close() error
- func (s *MemoryStore) CountRevokedTokens() (int, error)
- func (s *MemoryStore) DeleteTeam(name string) error
- func (s *MemoryStore) GetTeam(name string) (*TeamInfo, error)
- func (s *MemoryStore) IsTokenRevoked(tokenID string) (bool, error)
- func (s *MemoryStore) ListTeams() ([]TeamInfo, error)
- func (s *MemoryStore) RemoveRevokedToken(tokenID string) error
- func (s *MemoryStore) SaveRevokedToken(tokenID string, expiresAt time.Time) error
- func (s *MemoryStore) SaveTeam(team *TeamInfo) error
- type OIDCClaimMapping
- type OIDCConfig
- type OIDCValidator
- type Permission
- type RateLimitConfig
- type RateLimiter
- func (rl *RateLimiter) Close()
- func (rl *RateLimiter) GetBlockedIPs() []string
- func (rl *RateLimiter) IsBlocked(ip string) bool
- func (rl *RateLimiter) RecordFailure(ip string) bool
- func (rl *RateLimiter) RecordSuccess(ip string)
- func (rl *RateLimiter) Stats() RateLimiterStats
- func (rl *RateLimiter) Unblock(ip string)
- type RateLimiterStats
- type Role
- type SQLiteAuditStore
- type SQLiteAuditStoreConfig
- type SQLiteStore
- func (s *SQLiteStore) CleanupExpiredRevocations() (int, error)
- func (s *SQLiteStore) Close() error
- func (s *SQLiteStore) CountRevokedTokens() (int, error)
- func (s *SQLiteStore) DeleteTeam(name string) error
- func (s *SQLiteStore) GetTeam(name string) (*TeamInfo, error)
- func (s *SQLiteStore) IsTokenRevoked(tokenID string) (bool, error)
- func (s *SQLiteStore) ListTeams() ([]TeamInfo, error)
- func (s *SQLiteStore) RemoveRevokedToken(tokenID string) error
- func (s *SQLiteStore) SaveRevokedToken(tokenID string, expiresAt time.Time) error
- func (s *SQLiteStore) SaveTeam(team *TeamInfo) error
- type SQLiteStoreConfig
- type Store
- type TeamInfo
Constants ¶
This section is empty.
Variables ¶
var ( ErrInvalidToken = errors.New("invalid token") ErrTokenExpired = errors.New("token expired") ErrTokenRevoked = errors.New("token revoked") ErrForbidden = errors.New("forbidden") ErrTeamNotFound = errors.New("team not found") ErrInvalidSecret = errors.New("secret must be at least 16 bytes") ErrDuplicateTeam = errors.New("team already exists") ErrInvalidTeamName = errors.New("invalid team name") )
Sentinel errors for authentication.
var ErrAuthorizationPending = errors.New("authorization pending")
ErrAuthorizationPending is returned while the user has not yet completed auth.
var ErrNoCredentials = errors.New("no credentials found")
ErrNoCredentials is returned when no saved credentials are found.
var ErrSlowDown = errors.New("slow down polling")
ErrSlowDown is returned when polling too fast.
Functions ¶
func DefaultCredentialsPath ¶ added in v0.6.0
func DefaultCredentialsPath() string
DefaultCredentialsPath returns the default path for the credentials file.
func DefaultSQLiteAuditStorePath ¶ added in v0.6.0
func DefaultSQLiteAuditStorePath() string
DefaultSQLiteAuditStorePath returns the default audit database path.
func DefaultSQLiteStorePath ¶
func DefaultSQLiteStorePath() string
DefaultSQLiteStorePath returns the default path for the SQLite database.
func DeleteCredentials ¶ added in v0.6.0
DeleteCredentials removes the saved credentials for the given server.
func HasPermission ¶
func HasPermission(claims *Claims, perm Permission) bool
HasPermission checks if the claims grant the specified permission.
func PollDeviceFlow ¶ added in v0.6.0
func PollDeviceFlow(ctx context.Context, dc *DeviceCode) (string, error)
PollDeviceFlow polls the token endpoint until the user completes authorisation or the device code expires. It handles the "slow_down" and "authorization_pending" error responses automatically.
Types ¶
type AuditEvent ¶
type AuditEvent struct {
Timestamp time.Time `json:"timestamp"`
Type AuditEventType `json:"type"`
IP string `json:"ip,omitempty"`
TeamName string `json:"team,omitempty"`
Role string `json:"role,omitempty"`
SessionID string `json:"session_id,omitempty"`
Subdomain string `json:"subdomain,omitempty"`
TunnelID string `json:"tunnel_id,omitempty"`
Protocol string `json:"protocol,omitempty"`
Error string `json:"error,omitempty"`
Details map[string]interface{} `json:"details,omitempty"`
}
AuditEvent represents a single audit log entry.
type AuditEventType ¶
type AuditEventType string
AuditEventType represents the type of audit event.
const ( // EventAuthSuccess indicates successful authentication. EventAuthSuccess AuditEventType = "auth_success" // EventAuthFailure indicates failed authentication. EventAuthFailure AuditEventType = "auth_failure" // EventIPBlocked indicates an IP was blocked due to failures. EventIPBlocked AuditEventType = "ip_blocked" // EventIPUnblocked indicates an IP was manually unblocked. EventIPUnblocked AuditEventType = "ip_unblocked" // EventTokenGenerated indicates a new token was generated. EventTokenGenerated AuditEventType = "token_generated" // EventTokenRevoked indicates a token was revoked. EventTokenRevoked AuditEventType = "token_revoked" // EventTeamTokensRevoked indicates all tokens for a team were revoked. EventTeamTokensRevoked AuditEventType = "team_tokens_revoked" // #nosec G101 -- audit event type name, not a credential // EventClientConnected indicates a client connected. EventClientConnected AuditEventType = "client_connected" // EventClientDisconnected indicates a client disconnected. EventClientDisconnected AuditEventType = "client_disconnected" // EventTunnelCreated indicates a tunnel was created. EventTunnelCreated AuditEventType = "tunnel_created" // EventTunnelClosed indicates a tunnel was closed. EventTunnelClosed AuditEventType = "tunnel_closed" // EventP2PEstablished indicates a P2P connection was established. EventP2PEstablished AuditEventType = "p2p_established" // EventP2PFallback indicates a P2P attempt fell back to relay. EventP2PFallback AuditEventType = "p2p_fallback" )
type AuditLogger ¶
type AuditLogger struct {
// contains filtered or unexported fields
}
AuditLogger logs authentication and authorization events to a writer and optionally to a persistent AuditStore.
func NewAuditLogger ¶
func NewAuditLogger(config AuditLoggerConfig) *AuditLogger
NewAuditLogger creates a new audit logger.
func (*AuditLogger) IsEnabled ¶
func (l *AuditLogger) IsEnabled() bool
IsEnabled returns whether audit logging is enabled.
func (*AuditLogger) Log ¶
func (l *AuditLogger) Log(event AuditEvent)
Log writes an audit event to the log writer and, when configured, to the store.
func (*AuditLogger) LogAuthFailure ¶
func (l *AuditLogger) LogAuthFailure(ip, reason string)
LogAuthFailure logs a failed authentication event.
func (*AuditLogger) LogAuthSuccess ¶
func (l *AuditLogger) LogAuthSuccess(ip, teamName string, role Role, sessionID, subdomain string)
LogAuthSuccess logs a successful authentication event.
func (*AuditLogger) LogClientConnected ¶
func (l *AuditLogger) LogClientConnected(ip, sessionID, subdomain, teamName string, role Role)
LogClientConnected logs a client connection event.
func (*AuditLogger) LogClientDisconnected ¶
func (l *AuditLogger) LogClientDisconnected(sessionID, subdomain string, duration time.Duration)
LogClientDisconnected logs a client disconnection event.
func (*AuditLogger) LogIPBlocked ¶
func (l *AuditLogger) LogIPBlocked(ip string, failureCount int)
LogIPBlocked logs an IP blocking event.
func (*AuditLogger) LogIPUnblocked ¶
func (l *AuditLogger) LogIPUnblocked(ip string, manual bool)
LogIPUnblocked logs an IP unblocking event.
func (*AuditLogger) LogP2PEstablished ¶ added in v0.6.0
func (l *AuditLogger) LogP2PEstablished(sessionID, peerAddr string)
LogP2PEstablished logs a successful P2P connection establishment.
func (*AuditLogger) LogP2PFallback ¶ added in v0.6.0
func (l *AuditLogger) LogP2PFallback(sessionID, reason string)
LogP2PFallback logs a P2P failure that caused relay fallback.
func (*AuditLogger) LogTeamTokensRevoked ¶ added in v0.6.0
func (l *AuditLogger) LogTeamTokensRevoked(teamName string)
LogTeamTokensRevoked logs a team-level token revocation event.
func (*AuditLogger) LogTokenGenerated ¶
func (l *AuditLogger) LogTokenGenerated(teamName string, role Role)
LogTokenGenerated logs a token generation event.
func (*AuditLogger) LogTokenRevoked ¶ added in v0.6.0
func (l *AuditLogger) LogTokenRevoked(tokenID, teamName string)
LogTokenRevoked logs a token revocation event.
func (*AuditLogger) LogTunnelClosed ¶ added in v0.6.0
func (l *AuditLogger) LogTunnelClosed(sessionID, tunnelID, protocol, reason string)
LogTunnelClosed logs a tunnel closure event.
func (*AuditLogger) LogTunnelCreated ¶ added in v0.6.0
func (l *AuditLogger) LogTunnelCreated(sessionID, tunnelID, protocol, publicURL string)
LogTunnelCreated logs a tunnel creation event.
func (*AuditLogger) SetEnabled ¶
func (l *AuditLogger) SetEnabled(enabled bool)
SetEnabled enables or disables audit logging.
func (*AuditLogger) Store ¶ added in v0.6.0
func (l *AuditLogger) Store() AuditStore
Store returns the underlying AuditStore, if any.
type AuditLoggerConfig ¶
type AuditLoggerConfig struct {
// Enabled turns audit logging on or off.
Enabled bool
// Writer is the destination for JSON-line audit logs (defaults to os.Stdout).
Writer io.Writer
// Store is an optional persistent backend for structured queries.
// When set, every logged event is also stored for later retrieval.
Store AuditStore
}
AuditLoggerConfig configures the audit logger.
type AuditQuery ¶ added in v0.6.0
type AuditQuery struct {
// Type filters by event type (empty = all types).
Type AuditEventType
// From is the inclusive start time (zero = no lower bound).
From time.Time
// To is the inclusive end time (zero = no upper bound).
To time.Time
// TeamName filters by team (empty = all teams).
TeamName string
// SessionID filters by session (empty = all sessions).
SessionID string
// IP filters by client IP (empty = all IPs).
IP string
// Limit is the maximum number of events to return (0 = use store default).
Limit int
// Offset is the number of events to skip (for pagination).
Offset int
}
AuditQuery carries all filtering parameters for audit log retrieval.
type AuditStore ¶ added in v0.6.0
type AuditStore interface {
// Store persists a single audit event.
Store(event AuditEvent) error
// Query retrieves events matching the given filter.
Query(q AuditQuery) ([]AuditEvent, error)
// Close releases any held resources.
Close() error
}
AuditStore is the persistence interface for audit events. Implementations must be safe for concurrent use.
type Auth ¶
type Auth struct {
// contains filtered or unexported fields
}
Auth provides token-based authentication and authorization.
func NewSimple ¶
NewSimple creates an Auth instance for simple pre-shared token mode. In this mode, tokens are compared directly against the allowed list.
func (*Auth) CleanupRevokedTokens ¶
CleanupRevokedTokens removes expired entries from the revocation blacklist. This should be called periodically to prevent the blacklist from growing unbounded.
func (*Auth) Close ¶
Close releases any resources held by the Auth instance. This should be called when the Auth instance is no longer needed.
func (*Auth) ExtendTokenExpiry ¶
ExtendTokenExpiry creates a new token with an extended expiry time. The original token is NOT revoked.
func (*Auth) GenerateTeamToken ¶
GenerateTeamToken generates a new signed token for the given team and role.
func (*Auth) RefreshAndRevokeToken ¶
RefreshAndRevokeToken generates a new token and revokes the old one atomically. This is the recommended way to refresh tokens when rotation is desired.
func (*Auth) RefreshToken ¶
RefreshToken generates a new token with the same claims as the original, but with a fresh issuance time and expiry. The original token is NOT revoked. Use RevokeToken to invalidate the old token if desired.
func (*Auth) RegisterTeam ¶
RegisterTeam registers a team in the store.
func (*Auth) RevokeAllTeamTokens ¶
RevokeAllTeamTokens invalidates all existing tokens for a team by incrementing the team's revoked version. Any token whose version is less than or equal to the new revoked version will be rejected during validation. Returns ErrTeamNotFound if the team does not exist.
func (*Auth) RevokeToken ¶
RevokeToken adds a token ID to the revocation blacklist. The expiresAt parameter indicates when the token would have expired; after that time, the revocation entry can be cleaned up. If expiresAt is zero, the revocation is permanent until manually cleared.
func (*Auth) RevokeTokenByString ¶
RevokeTokenByString parses a token string and revokes it by ID. Returns ErrInvalidToken if the token cannot be parsed or has no ID.
func (*Auth) RevokedTokenCount ¶
RevokedTokenCount returns the number of tokens in the revocation blacklist.
func (*Auth) SetOIDCValidator ¶ added in v0.6.0
func (a *Auth) SetOIDCValidator(v *OIDCValidator)
SetOIDCValidator configures an OIDC JWT validator. When set, JWT-shaped tokens are validated via OIDC before trying the HMAC path.
func (*Auth) Store ¶
Store returns the underlying storage backend. This is useful for advanced operations or testing.
func (*Auth) UnrevokeToken ¶
UnrevokeToken removes a token ID from the revocation blacklist.
func (*Auth) ValidateToken ¶
ValidateToken validates a token and returns its claims. Validation order:
- Pre-shared simple tokens (exact match).
- OIDC JWT validation (when an OIDCValidator is configured and token is a JWT).
- HMAC-signed token validation.
type Claims ¶
type Claims struct {
// TokenID is the unique identifier for this token.
TokenID string `json:"jti,omitempty"`
// TeamName is the team this token belongs to.
TeamName string `json:"team"`
// Role is the role assigned to this token.
Role Role `json:"role"`
// IssuedAt is when the token was issued.
IssuedAt time.Time `json:"iat"`
// ExpiresAt is when the token expires (zero means no expiry).
ExpiresAt time.Time `json:"exp,omitempty"`
}
Claims contains the validated token information.
type Config ¶
type Config struct {
// Secret is the HMAC signing key (must be at least 16 bytes).
Secret []byte
// TokenExpiry is the default expiry duration for new tokens.
TokenExpiry time.Duration
// AllowedTokens is a list of pre-shared plain tokens (simple mode).
// When set, these tokens bypass HMAC validation entirely.
AllowedTokens []string
// Store is the storage backend for teams and revoked tokens.
// If nil, a MemoryStore is used (no persistence).
Store Store
}
Config holds the authentication configuration.
type Credentials ¶ added in v0.6.0
type Credentials struct {
// Server is the wormhole server address these credentials are for.
Server string `json:"server"`
// Token is the saved OAuth/OIDC access or ID token.
Token string `json:"token"`
// ExpiresAt is when the token expires (zero means no expiry).
ExpiresAt time.Time `json:"expires_at,omitempty"`
// SavedAt records when the credentials were persisted.
SavedAt time.Time `json:"saved_at"`
}
Credentials stores an OAuth/OIDC access token alongside its metadata.
func LoadCredentials ¶ added in v0.6.0
func LoadCredentials(path, server string) (*Credentials, error)
LoadCredentials reads the saved credentials for the given server. Returns ErrNoCredentials when no entry exists.
func (*Credentials) IsExpired ¶ added in v0.6.0
func (c *Credentials) IsExpired() bool
IsExpired returns true if the token has expired.
type DeviceCode ¶ added in v0.6.0
type DeviceCode struct {
// DeviceCode is the opaque code sent to the token endpoint.
DeviceCode string
// UserCode is the short code the user enters at VerificationURI.
UserCode string
// VerificationURI is the URL the user should visit to complete authorisation.
VerificationURI string
// VerificationURIComplete includes the user code for one-click auth (optional).
VerificationURIComplete string
// ExpiresIn is the number of seconds until the codes expire.
ExpiresIn int
// Interval is the polling interval in seconds (default 5).
Interval int
// TokenEndpoint is the endpoint to poll for a token.
TokenEndpoint string
}
DeviceCode holds the values returned by the device authorization endpoint.
func StartDeviceFlow ¶ added in v0.6.0
func StartDeviceFlow(ctx context.Context, cfg DeviceFlowConfig) (*DeviceCode, error)
StartDeviceFlow initiates the OAuth2 Device Authorization Grant. It discovers the device authorization and token endpoints from the OIDC well-known configuration, then starts the flow.
type DeviceFlowConfig ¶ added in v0.6.0
type DeviceFlowConfig struct {
// Issuer is the OIDC provider URL used for endpoint discovery.
Issuer string
// ClientID is the OAuth2 public client registered with the provider.
ClientID string
// Scopes is the list of OAuth scopes to request.
// Defaults to ["openid", "email", "profile"] when empty.
Scopes []string
}
DeviceFlowConfig configures an OAuth2 Device Authorization Grant flow.
type MemoryAuditStore ¶ added in v0.6.0
type MemoryAuditStore struct {
// contains filtered or unexported fields
}
MemoryAuditStore holds the most recent N audit events in memory. Older events are silently dropped when the buffer is full.
func NewMemoryAuditStore ¶ added in v0.6.0
func NewMemoryAuditStore(capacity int) *MemoryAuditStore
NewMemoryAuditStore creates a ring-buffer audit store with the given capacity. A capacity of 0 uses a default of 10 000.
func (*MemoryAuditStore) Close ¶ added in v0.6.0
func (m *MemoryAuditStore) Close() error
Close is a no-op for the in-memory store.
func (*MemoryAuditStore) Query ¶ added in v0.6.0
func (m *MemoryAuditStore) Query(q AuditQuery) ([]AuditEvent, error)
Query returns events matching the filter in reverse-chronological order (newest first), applying Offset and Limit.
func (*MemoryAuditStore) Store ¶ added in v0.6.0
func (m *MemoryAuditStore) Store(event AuditEvent) error
Store appends an event to the ring buffer.
type MemoryStore ¶
type MemoryStore struct {
// contains filtered or unexported fields
}
MemoryStore implements Store using in-memory maps. This is the default, zero-persistence backend.
func NewMemoryStore ¶
func NewMemoryStore() *MemoryStore
NewMemoryStore creates a new in-memory store.
func (*MemoryStore) CleanupExpiredRevocations ¶
func (s *MemoryStore) CleanupExpiredRevocations() (int, error)
CleanupExpiredRevocations removes expired revocation entries.
func (*MemoryStore) CountRevokedTokens ¶
func (s *MemoryStore) CountRevokedTokens() (int, error)
CountRevokedTokens returns the number of revoked tokens.
func (*MemoryStore) DeleteTeam ¶
func (s *MemoryStore) DeleteTeam(name string) error
DeleteTeam removes a team from memory.
func (*MemoryStore) GetTeam ¶
func (s *MemoryStore) GetTeam(name string) (*TeamInfo, error)
GetTeam retrieves a team from memory.
func (*MemoryStore) IsTokenRevoked ¶
func (s *MemoryStore) IsTokenRevoked(tokenID string) (bool, error)
IsTokenRevoked checks if a token is revoked.
func (*MemoryStore) ListTeams ¶
func (s *MemoryStore) ListTeams() ([]TeamInfo, error)
ListTeams returns all teams from memory.
func (*MemoryStore) RemoveRevokedToken ¶
func (s *MemoryStore) RemoveRevokedToken(tokenID string) error
RemoveRevokedToken removes a token from the revocation list.
func (*MemoryStore) SaveRevokedToken ¶
func (s *MemoryStore) SaveRevokedToken(tokenID string, expiresAt time.Time) error
SaveRevokedToken saves a revoked token to memory.
func (*MemoryStore) SaveTeam ¶
func (s *MemoryStore) SaveTeam(team *TeamInfo) error
SaveTeam saves a team to memory.
type OIDCClaimMapping ¶ added in v0.6.0
type OIDCClaimMapping struct {
// TeamClaim is the JWT claim used as the Wormhole team name.
// Defaults to "email" when empty.
TeamClaim string
// RoleClaim is an optional JWT claim for the Wormhole role.
// Supports values: "admin", "member", "viewer".
// When absent or unrecognized, DefaultRole is used.
RoleClaim string
// DefaultRole is the role assigned when RoleClaim is absent.
// Defaults to RoleMember.
DefaultRole Role
}
OIDCClaimMapping configures the mapping of OIDC claims to Wormhole identity fields.
type OIDCConfig ¶ added in v0.6.0
type OIDCConfig struct {
// Issuer is the OIDC provider URL (e.g. "https://accounts.google.com").
// The well-known configuration will be fetched from <Issuer>/.well-known/openid-configuration.
Issuer string
// ClientID is the OAuth2 client ID registered with the provider.
ClientID string
// Audience is the expected JWT audience claim.
// Defaults to ClientID when empty.
Audience string
// ClaimMapping configures how OIDC claims are mapped to Wormhole roles.
ClaimMapping OIDCClaimMapping
}
OIDCConfig holds the OIDC provider configuration.
type OIDCValidator ¶ added in v0.6.0
type OIDCValidator struct {
// contains filtered or unexported fields
}
OIDCValidator validates JWT tokens issued by an OIDC provider. It fetches the JWKS from the provider's discovery endpoint and caches the signing keys. The cache is refreshed every 15 minutes or on key miss.
func NewOIDCValidator ¶ added in v0.6.0
func NewOIDCValidator(config OIDCConfig) (*OIDCValidator, error)
NewOIDCValidator creates an OIDCValidator and performs the OIDC discovery.
func (*OIDCValidator) ValidateToken ¶ added in v0.6.0
func (v *OIDCValidator) ValidateToken(tokenStr string) (*Claims, error)
ValidateToken validates an OIDC JWT and returns Wormhole Claims.
type Permission ¶
type Permission string
Permission represents an action that can be authorized.
const ( // PermissionConnect allows establishing a tunnel connection. PermissionConnect Permission = "connect" // PermissionWrite allows creating and managing tunnels. PermissionWrite Permission = "write" // PermissionRead allows viewing tunnels and statistics. PermissionRead Permission = "read" // PermissionAdmin allows administrative operations. PermissionAdmin Permission = "admin" )
type RateLimitConfig ¶
type RateLimitConfig struct {
// MaxFailures is the maximum number of auth failures before blocking.
MaxFailures int
// Window is the time window for counting failures.
Window time.Duration
// BlockDuration is how long to block after exceeding MaxFailures.
BlockDuration time.Duration
// CleanupInterval is how often to clean up expired entries.
CleanupInterval time.Duration
}
RateLimitConfig configures the rate limiter behavior.
func DefaultRateLimitConfig ¶
func DefaultRateLimitConfig() RateLimitConfig
DefaultRateLimitConfig returns sensible defaults for rate limiting.
type RateLimiter ¶
type RateLimiter struct {
// contains filtered or unexported fields
}
RateLimiter tracks authentication failures and blocks IPs.
func NewRateLimiter ¶
func NewRateLimiter(config RateLimitConfig) *RateLimiter
NewRateLimiter creates a new rate limiter with the given config.
func (*RateLimiter) Close ¶
func (rl *RateLimiter) Close()
Close stops the rate limiter and its cleanup goroutine.
func (*RateLimiter) GetBlockedIPs ¶
func (rl *RateLimiter) GetBlockedIPs() []string
GetBlockedIPs returns a list of currently blocked IP addresses.
func (*RateLimiter) IsBlocked ¶
func (rl *RateLimiter) IsBlocked(ip string) bool
IsBlocked checks if the given IP is currently blocked.
func (*RateLimiter) RecordFailure ¶
func (rl *RateLimiter) RecordFailure(ip string) bool
RecordFailure records an authentication failure for the given IP. Returns true if the IP is now blocked.
func (*RateLimiter) RecordSuccess ¶
func (rl *RateLimiter) RecordSuccess(ip string)
RecordSuccess records a successful authentication, clearing failure count.
func (*RateLimiter) Stats ¶
func (rl *RateLimiter) Stats() RateLimiterStats
Stats returns current rate limiter statistics.
func (*RateLimiter) Unblock ¶
func (rl *RateLimiter) Unblock(ip string)
Unblock manually unblocks an IP address.
type RateLimiterStats ¶
type RateLimiterStats struct {
TrackedIPs int `json:"tracked_ips"`
BlockedIPs int `json:"blocked_ips"`
}
Stats returns rate limiter statistics.
type SQLiteAuditStore ¶ added in v0.6.0
type SQLiteAuditStore struct {
// contains filtered or unexported fields
}
SQLiteAuditStore persists audit events to a SQLite database.
func NewSQLiteAuditStore ¶ added in v0.6.0
func NewSQLiteAuditStore(cfg SQLiteAuditStoreConfig) (*SQLiteAuditStore, error)
NewSQLiteAuditStore opens (or creates) a SQLite audit store.
func (*SQLiteAuditStore) Close ¶ added in v0.6.0
func (s *SQLiteAuditStore) Close() error
Close closes the underlying database.
func (*SQLiteAuditStore) Query ¶ added in v0.6.0
func (s *SQLiteAuditStore) Query(q AuditQuery) ([]AuditEvent, error)
Query retrieves audit events matching the given filter (newest first).
func (*SQLiteAuditStore) Store ¶ added in v0.6.0
func (s *SQLiteAuditStore) Store(event AuditEvent) error
Store inserts one audit event into the database.
type SQLiteAuditStoreConfig ¶ added in v0.6.0
type SQLiteAuditStoreConfig struct {
// Path is the file path for the SQLite database.
// Defaults to ~/.wormhole/audit.db when empty.
Path string
// CreateDir creates the parent directory if it doesn't exist.
CreateDir bool
}
SQLiteAuditStoreConfig configures the SQLite audit store.
type SQLiteStore ¶
type SQLiteStore struct {
// contains filtered or unexported fields
}
SQLiteStore implements Store using SQLite for persistence.
func NewSQLiteStore ¶
func NewSQLiteStore(config SQLiteStoreConfig) (*SQLiteStore, error)
NewSQLiteStore creates a new SQLite-backed store.
func (*SQLiteStore) CleanupExpiredRevocations ¶
func (s *SQLiteStore) CleanupExpiredRevocations() (int, error)
CleanupExpiredRevocations removes expired revocation entries.
func (*SQLiteStore) Close ¶
func (s *SQLiteStore) Close() error
Close closes the database connection.
func (*SQLiteStore) CountRevokedTokens ¶
func (s *SQLiteStore) CountRevokedTokens() (int, error)
CountRevokedTokens returns the number of revoked tokens.
func (*SQLiteStore) DeleteTeam ¶
func (s *SQLiteStore) DeleteTeam(name string) error
DeleteTeam removes a team from SQLite.
func (*SQLiteStore) GetTeam ¶
func (s *SQLiteStore) GetTeam(name string) (*TeamInfo, error)
GetTeam retrieves a team from SQLite.
func (*SQLiteStore) IsTokenRevoked ¶
func (s *SQLiteStore) IsTokenRevoked(tokenID string) (bool, error)
IsTokenRevoked checks if a token is revoked.
func (*SQLiteStore) ListTeams ¶
func (s *SQLiteStore) ListTeams() ([]TeamInfo, error)
ListTeams returns all teams from SQLite.
func (*SQLiteStore) RemoveRevokedToken ¶
func (s *SQLiteStore) RemoveRevokedToken(tokenID string) error
RemoveRevokedToken removes a token from the revocation list.
func (*SQLiteStore) SaveRevokedToken ¶
func (s *SQLiteStore) SaveRevokedToken(tokenID string, expiresAt time.Time) error
SaveRevokedToken saves a revoked token to SQLite.
func (*SQLiteStore) SaveTeam ¶
func (s *SQLiteStore) SaveTeam(team *TeamInfo) error
SaveTeam saves a team to SQLite.
type SQLiteStoreConfig ¶
type SQLiteStoreConfig struct {
// Path is the path to the SQLite database file.
// If empty, defaults to ~/.wormhole/wormhole.db
Path string
// CreateDir creates the parent directory if it doesn't exist.
CreateDir bool
}
SQLiteStoreConfig configures the SQLite store.
type Store ¶
type Store interface {
// Team operations.
SaveTeam(team *TeamInfo) error
GetTeam(name string) (*TeamInfo, error)
ListTeams() ([]TeamInfo, error)
DeleteTeam(name string) error
// Token revocation operations.
SaveRevokedToken(tokenID string, expiresAt time.Time) error
IsTokenRevoked(tokenID string) (bool, error)
RemoveRevokedToken(tokenID string) error
CleanupExpiredRevocations() (int, error)
CountRevokedTokens() (int, error)
// Close releases any resources held by the store.
Close() error
}
Store defines the interface for persisting authentication data. Implementations can be in-memory (default) or persistent (SQLite).