Documentation
¶
Overview ¶
Package auth holds the token model, argon2id hashing, scope checks, and the SQLite-backed token store. (M2)
Index ¶
- Variables
- func DefaultPath(stateDir string) string
- func Has(scopes []string, required Scope) bool
- func ParseScopes(s string) ([]string, error)
- type CreateOptions
- type Scope
- type Store
- func (s *Store) Authenticate(ctx context.Context, bearer string) (*Token, error)
- func (s *Store) Close() error
- func (s *Store) Count(ctx context.Context) (int, error)
- func (s *Store) Create(ctx context.Context, opts CreateOptions) (string, *Token, error)
- func (s *Store) DB() *sql.DB
- func (s *Store) List(ctx context.Context) ([]*Token, error)
- func (s *Store) ResolveIDOrName(ctx context.Context, idOrName string) (string, error)
- func (s *Store) Revoke(ctx context.Context, id string) error
- func (s *Store) Rotate(ctx context.Context, id string) (string, *Token, error)
- func (s *Store) SeedFromBearer(ctx context.Context, bearer string) (int, error)
- func (s *Store) SetDebugCapture(ctx context.Context, id string, enabled bool) error
- type Token
Constants ¶
This section is empty.
Variables ¶
var ErrInvalidToken = errors.New("invalid token")
ErrInvalidToken is returned when the bearer can't be authenticated.
var ErrUnknownToken = errors.New("token not found")
ErrUnknownToken is returned by management calls when no row matches.
Functions ¶
func DefaultPath ¶
Path returns a likely default location for the token DB given a state dir.
func Has ¶
Has reports whether scopes contains required, treating workspace:* as a supergrant over any workspace:<name>.
func ParseScopes ¶
ParseScopes splits a comma-separated list and validates each entry.
Types ¶
type CreateOptions ¶
type CreateOptions struct {
Name string
Scopes []string
TTL time.Duration // 0 = no expiry
RateLimitRPM int
RateLimitTPD int
DebugCapture bool
DefaultVerbosity string
// Principal opaquely groups tokens that should share a bridge
// attachment. See Token.Principal.
Principal string
}
CreateOptions describes a new token request.
type Scope ¶
type Scope string
Scope is a single permission grant. Scopes follow PRD §6.6.
const ( ScopeChat Scope = "chat" ScopeSessionPersistent Scope = "session:persistent" ScopeAdmin Scope = "admin" // ScopeWorkspaceWildcard grants access to every configured workspace. ScopeWorkspaceWildcard Scope = "workspace:*" // ScopeBridgeConnect lets a token open a /bridge websocket and register // the bridge daemon under the token's Principal. Chat tokens do NOT need // this scope — their bridge attachment happens implicitly when they // share a Principal with a connected bridge. ScopeBridgeConnect Scope = "bridge:connect" )
func WorkspaceScope ¶
WorkspaceScope returns the scope value for one named workspace.
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store is the SQLite-backed token registry. It is safe for concurrent use.
func Open ¶
Open opens (and creates if needed) the token DB at path. The directory must already exist.
func (*Store) Authenticate ¶
Authenticate resolves a bearer string to a Token. It first checks the in-memory cache; cache misses pay the argon2id cost.
func (*Store) Create ¶
Create inserts a new token row and returns the bearer string (which MUST be displayed to the user once — it is not recoverable from the DB) and the persisted Token record.
func (*Store) DB ¶
DB returns the underlying *sql.DB so other components (e.g. ratelimit) can share the same SQLite connection pool.
func (*Store) ResolveIDOrName ¶
ResolveIDOrName returns the token id for a string that might already be an id or might be a unique name. Unknown or ambiguous values return ErrUnknownToken. Useful for CLI commands that take an identifier.
func (*Store) Rotate ¶
Rotate generates a new bearer for an existing token id, invalidating the previous one. Scopes / limits / name are preserved.
func (*Store) SeedFromBearer ¶
SeedFromBearer is the M1→M2 migration path: if the DB has no tokens and a non-empty bearer is provided (e.g. from the legacy CCPROXY_TOKEN env), create one with chat scope and return it. Otherwise it's a no-op.
SeedFromBearer can only seed the env value if it is in the new ccp_<prefix>_<secret> format; arbitrary strings can't be backfilled because the prefix-indexed lookup needs the structured shape. Returns the count of tokens after the call so callers can warn appropriately.
func (*Store) SetDebugCapture ¶
SetDebugCapture flips the debug_capture flag on an existing token row. Takes effect on the next auth after the in-memory cache entry expires (default TTL 2m) — or immediately for tokens not yet cached.
type Token ¶
type Token struct {
ID string
Name string
Prefix string
Scopes []string
CreatedAt time.Time
LastUsedAt *time.Time
ExpiresAt *time.Time
RateLimitRPM int
RateLimitTPD int
DebugCapture bool
DefaultVerb string
// Principal is an opaque identifier for the token's owner. Tokens
// sharing a principal share a bridge attachment: when a bridge daemon
// authenticated with principal P is connected, chat requests from
// tokens with the same principal whose workspace would otherwise be
// ephemeral resolve to the bridge mount instead. Empty principal means
// the token participates in no bridge.
Principal string
}
Token is the persisted record minus the secret hash (which never leaves the store).