Documentation
¶
Overview ¶
Package mcp_headers implements schemas.MCPHeadersProvider against the configstore. It is the storage backend for MCPAuthTypePerUserHeaders MCP clients — the parallel of framework/oauth2 for the OAuth-flavored per-user auth type.
The provider is intentionally storage-only: it does not run upstream verification (that's clientmanager.VerifyHeadersConnection) and does not build inline-401 errors (that's the credstore resolver). It just maps between the table type and the in-memory schema view.
Index ¶
- Constants
- type CredentialSweepWorker
- type Provider
- func (p *Provider) DeleteCredential(ctx context.Context, id string) error
- func (p *Provider) GetCredentialByMode(ctx context.Context, mode schemas.MCPAuthMode, identity, mcpClientID string) (*schemas.MCPHeadersUserCredential, error)
- func (p *Provider) InitiateUserSubmissionFlow(ctx context.Context, mode schemas.MCPAuthMode, ...) (*schemas.MCPHeadersFlowInitiation, error)
- func (p *Provider) SetTempTokenService(svc *temptoken.Service)
- func (p *Provider) UpsertCredential(ctx context.Context, cred *schemas.MCPHeadersUserCredential) error
Constants ¶
const SubmissionFlowTTL = 15 * time.Minute
SubmissionFlowTTL caps how long a pending headers submission flow row (and the temp token bound to it) remains valid. Mirrors the OAuth flow expiry so the two per-user-auth surfaces feel uniform to the user.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type CredentialSweepWorker ¶
type CredentialSweepWorker struct {
// contains filtered or unexported fields
}
CredentialSweepWorker periodically purges stale per-user header credentials AND expired pending submission-flow rows. Two independent sweeps run on the same goroutine:
- Orphan credential sweep: rows that have been in 'orphaned' state (VK lost access) longer than OrphanRetention are hard-deleted.
- Expired flow sweep: pending flow rows whose ExpiresAt has passed (caller never completed the submission, link aged out) are hard-deleted. Tighter cadence than the orphan sweep because flow rows are short-lived (15 min TTL).
Mirrors oauth2.PerUserOAuthSweepWorker, which combines the same two concerns on the OAuth side.
Defaults: 24h orphan cadence, 15 min flow-expiry cadence. Non-positive orphanRetention disables the orphan sweep entirely; the expired-flow sweep always runs because flow rows have no semantic value past their expiry.
func NewCredentialSweepWorker ¶
func NewCredentialSweepWorker(provider *Provider, orphanRetention time.Duration, logger schemas.Logger) *CredentialSweepWorker
NewCredentialSweepWorker creates a sweep worker with sensible defaults. orphanRetention <= 0 disables the orphan sweep (the worker still starts but the tick is a no-op — keeps wiring uniform).
func (*CredentialSweepWorker) SetOrphanSweepInterval ¶
func (w *CredentialSweepWorker) SetOrphanSweepInterval(d time.Duration)
SetOrphanSweepInterval updates the orphan-sweep cadence (for testing). Non-positive durations are ignored — run() feeds the field straight into time.NewTicker, which panics on d <= 0.
func (*CredentialSweepWorker) Start ¶
func (w *CredentialSweepWorker) Start(ctx context.Context)
Start begins the sweep worker in a background goroutine.
func (*CredentialSweepWorker) Stop ¶
func (w *CredentialSweepWorker) Stop()
Stop gracefully stops the sweep worker. sync.Once guards against double-close panics from redundant shutdown paths.
type Provider ¶
type Provider struct {
// contains filtered or unexported fields
}
Provider implements schemas.MCPHeadersProvider.
func NewProvider ¶
func NewProvider(configStore configstore.ConfigStore, logger schemas.Logger) *Provider
NewProvider constructs a configstore-backed MCPHeadersProvider. Mirrors oauth2.NewOAuth2Provider so the wiring in transports/bifrost-http stays symmetric between the two per-user auth surfaces.
func (*Provider) DeleteCredential ¶
DeleteCredential removes a credential by primary key.
func (*Provider) GetCredentialByMode ¶
func (p *Provider) GetCredentialByMode(ctx context.Context, mode schemas.MCPAuthMode, identity, mcpClientID string) (*schemas.MCPHeadersUserCredential, error)
GetCredentialByMode looks up the active credential row for the given identity dimension. Returns ErrHeadersCredentialNotFound when the row is absent so callers can switch on the sentinel.
func (*Provider) InitiateUserSubmissionFlow ¶
func (p *Provider) InitiateUserSubmissionFlow(ctx context.Context, mode schemas.MCPAuthMode, identity, mcpClientID, baseURL string) (*schemas.MCPHeadersFlowInitiation, error)
InitiateUserSubmissionFlow creates a pending mcp_per_user_header_flows row keyed by (mode, identity, mcp_client_id), mints a mcp_headers_auth temp-token bound to the new row's ID, and returns the auth-page URL with the token embedded as a `#t=<token>` fragment. Mirrors oauth2.OAuth2Provider.InitiateUserOAuthFlow.
The temp-token mint is best-effort: if it fails, the URL is returned without a fragment and remains usable for callers already authenticated to the dashboard. The behavior is the same as the OAuth equivalent so the two surfaces feel uniform.
func (*Provider) SetTempTokenService ¶
SetTempTokenService installs the temp-token service used by InitiateUserSubmissionFlow to mint the mcp_headers_auth token embedded in the auth-page URL fragment. Called by server startup once both services have been constructed (the provider is built first by lib/config.go, the service later by the HTTP transport).
func (*Provider) UpsertCredential ¶
func (p *Provider) UpsertCredential(ctx context.Context, cred *schemas.MCPHeadersUserCredential) error
UpsertCredential persists the caller-supplied credential. The caller is expected to have run clientmanager.VerifyHeadersConnection before invoking this — the provider trusts the values and only handles serialization + storage.