Documentation
¶
Overview ¶
SPDX-License-Identifier: Apache-2.0 Extracted from Viant Agently Core.
SPDX-License-Identifier: Apache-2.0 Extracted from Viant Agently Core.
SPDX-License-Identifier: Apache-2.0 Extracted from Viant Agently Core.
SPDX-License-Identifier: Apache-2.0 Extracted from Viant Agently Core.
SPDX-License-Identifier: Apache-2.0 Extracted from Viant Agently Core.
SPDX-License-Identifier: Apache-2.0 Extracted from Viant Agently Core.
SPDX-License-Identifier: Apache-2.0 Extracted from Viant Agently Core.
SPDX-License-Identifier: Apache-2.0 Extracted from Viant Agently Core.
SPDX-License-Identifier: Apache-2.0 Extracted from Viant Agently Core.
Index ¶
- Constants
- Variables
- func Bearer(ctx context.Context) string
- func CanonicalUserID(ctx context.Context) string
- func CanonicalWorkspaceProvider(cfg *Config, provider string) string
- func DelegatedProviderStorageKey(workspaceNamespace, providerRef string) string
- func EffectiveUserID(ctx context.Context) string
- func IDToken(ctx context.Context) string
- func InjectTokens(ctx context.Context, tokens *scyauth.Token) context.Context
- func InjectUser(ctx context.Context, subject string) context.Context
- func IsDelegatedProviderKey(provider string) bool
- func IsWorkspaceProviderAlias(cfg *Config, provider string) bool
- func MCPAuthToken(ctx context.Context, useIDToken bool) string
- func OAuthScopesForHeadless(client *OAuthClient) []string
- func Provider(ctx context.Context) string
- func TokensFromContext(ctx context.Context) *scyauth.Token
- func ValidateOAuthTokenScopes(expected []string, token *scyauth.Token) error
- func VerifiedProvider(ctx context.Context) string
- func WithBearer(ctx context.Context, value string) context.Context
- func WithCanonicalUserID(ctx context.Context, value string) context.Context
- func WithIDToken(ctx context.Context, value string) context.Context
- func WithProvider(ctx context.Context, value string) context.Context
- func WithTokens(ctx context.Context, tokens *scyauth.Token) context.Context
- func WithUserInfo(ctx context.Context, info *UserInfo) context.Context
- func WithoutTokens(ctx context.Context) context.Context
- type Config
- type DelegatedCredentialResolver
- func (r *DelegatedCredentialResolver) Invalidate(ctx context.Context, requirement authcfg.Requirement) error
- func (r *DelegatedCredentialResolver) MaxRefreshLead(ctx context.Context) time.Duration
- func (r *DelegatedCredentialResolver) Refresh(ctx context.Context, requirement authcfg.Requirement) (*authcfg.Credential, error)
- func (r *DelegatedCredentialResolver) RefreshStoredDelegatedToken(ctx context.Context, stored *OAuthToken) error
- func (r *DelegatedCredentialResolver) Resolve(ctx context.Context, requirement authcfg.Requirement) (*authcfg.Credential, error)
- type DelegatedMCPAuth
- type DelegatedTokenLister
- type DelegatedTokenRefresher
- type DelegatedTokenStore
- type ExpiringTokenScanner
- type MCPAuthChangeEvent
- type MCPAuthConfigProvider
- type MCPAuthState
- type MCPLinkBackend
- func (b *MCPLinkBackend) Complete(ctx context.Context, identity MCPLinkIdentity, code, state string) (*MCPLinkCompletion, error)
- func (b *MCPLinkBackend) Initiate(ctx context.Context, identity MCPLinkIdentity, ...) (*MCPLinkInitiation, error)
- func (b *MCPLinkBackend) Invalidate(ctx context.Context, identity MCPLinkIdentity, requirement authcfg.Requirement) error
- func (b *MCPLinkBackend) Refresh(ctx context.Context, identity MCPLinkIdentity, requirement authcfg.Requirement) (*authcfg.Credential, error)
- func (b *MCPLinkBackend) Resolve(ctx context.Context, identity MCPLinkIdentity, requirement authcfg.Requirement) (*authcfg.Credential, error)
- func (b *MCPLinkBackend) Status(ctx context.Context, identity MCPLinkIdentity, server string) (*MCPLinkStatus, error)
- type MCPLinkCompletion
- type MCPLinkIdentity
- type MCPLinkInitiation
- type MCPLinkStatus
- type OAuth
- type OAuthClient
- type OAuthStateRecord
- type OAuthStateStore
- type OAuthToken
- type PreferencesPatch
- type Session
- type TokenStore
- type User
- type UserByIDLookup
- type UserInfo
- type UserService
Constants ¶
const DelegatedProviderKeyLength = len(DelegatedProviderKeyPrefix) + sha256.Size*2
DelegatedProviderKeyLength is the fixed length of a delegated storage key: len("mcp:v1:") + 64 hex characters of an untruncated SHA-256 digest.
const DelegatedProviderKeyPrefix = "mcp:v1:"
DelegatedProviderKeyPrefix marks provider column values holding delegated (per-MCP-provider) tokens rather than workspace provider names.
Variables ¶
var ErrOAuthStateInvalid = errors.New("oauth link state is invalid")
Functions ¶
func CanonicalUserID ¶
CanonicalUserID reads only the host-established canonical identity.
func CanonicalWorkspaceProvider ¶
CanonicalWorkspaceProvider normalizes trusted workspace provider aliases ("", "jwt", "oauth", "default") to the configured workspace provider name. Delegated storage keys and unknown provider names pass through unchanged.
func DelegatedProviderStorageKey ¶
DelegatedProviderStorageKey derives the fixed-length, globally unambiguous user_oauth_token.provider value for a delegated provider reference:
mcp:v1:<hex sha256(workspaceNamespace + NUL + providerRef)>
The digest is never truncated. workspaceNamespace is an immutable configured identifier; changing it requires an explicit token-key migration.
func EffectiveUserID ¶
EffectiveUserID reads the host-established presentation identity for token partitioning.
func IDToken ¶
IDToken returns only the original ID token stored by trusted ingress. It never falls back to an access token; user-info ACL facts require the former.
func InjectTokens ¶
InjectTokens stores OAuth tokens in context so that MCPAuthToken and downstream MCP clients can forward the logged-in user's token. External auth middleware (outside this module) should call this after authenticating the user from a session or JWT.
func InjectUser ¶
InjectUser carries host-supplied user identity for the delegated credential resolver. External middleware (outside this module) can call this to bridge their own auth context into the context key that EffectiveUserID reads.
func IsDelegatedProviderKey ¶
IsDelegatedProviderKey reports whether a provider column value is a delegated storage key. Delegated rows require exact lookup and per-provider broker routing; they must never be served by workspace fallback or sent to the workspace refresh broker.
func IsWorkspaceProviderAlias ¶
IsWorkspaceProviderAlias reports whether provider names the workspace identity provider (directly or through a trusted legacy alias).
func MCPAuthToken ¶
MCPAuthToken selects a single token string suitable for outbound MCP calls. Delegates to the internal auth package.
func OAuthScopesForHeadless ¶
func OAuthScopesForHeadless(client *OAuthClient) []string
OAuthScopesForHeadless returns the grant a non-interactive user-owned runtime should request. A dedicated CLI scope wins; otherwise legacy browser-created schedules inherit the web scope, with mobile as the final compatibility fallback.
func ValidateOAuthTokenScopes ¶
ValidateOAuthTokenScopes validates a newly obtained OAuth token against the exact scopes requested for that authorization flow.
func VerifiedProvider ¶
VerifiedProvider reads the provider identifier established by host ingress.
func WithCanonicalUserID ¶
func WithTokens ¶
WithTokens stores only the token bundle. It preserves independent ingress bearer/ID-token values; InjectTokens is the explicit ingress convenience API.
Types ¶
type Config ¶
type Config struct {
OnCredentialChange func(MCPAuthChangeEvent) `json:"-" yaml:"-"`
WorkspaceNamespace string `json:"workspaceNamespace,omitempty" yaml:"workspaceNamespace,omitempty"`
TokenEncryptionKey string `json:"tokenEncryptionKey,omitempty" yaml:"tokenEncryptionKey,omitempty"`
StateEncryptionKey string `json:"stateEncryptionKey,omitempty" yaml:"stateEncryptionKey,omitempty"`
StateEncryptionKeyPrevious string `json:"stateEncryptionKeyPrevious,omitempty" yaml:"stateEncryptionKeyPrevious,omitempty"`
MCPLinkStateTTLMinutes int `json:"mcpLinkStateTTLMinutes,omitempty" yaml:"mcpLinkStateTTLMinutes,omitempty"`
// OAuth preserves legacy configURL-derived key selection during migration.
OAuth *OAuth `json:"oauth,omitempty" yaml:"oauth,omitempty"`
}
Config configures the MCP authorization-code and delegated credential lifecycle. It does not configure application ingress, users, policies or login sessions.
func (*Config) DelegatedTokenEncryptionSalt ¶
type DelegatedCredentialResolver ¶
type DelegatedCredentialResolver struct {
// contains filtered or unexported fields
}
DelegatedCredentialResolver implements the viant/mcp CredentialResolver for Agently: canonical-user-keyed encrypted storage, validated workspace-token reuse, provider-exact refresh with distributed leases and CAS, and safe invalidation. Resolution returns outbound credentials only — it never installs values into the Agently authentication context.
func NewDelegatedCredentialResolver ¶
func NewDelegatedCredentialResolver(cfg *Config, store DelegatedTokenStore, registry *providerregistry.Registry, namespace string) *DelegatedCredentialResolver
NewDelegatedCredentialResolver builds the resolver. namespace is the immutable workspace namespace used in storage-key derivation.
func (*DelegatedCredentialResolver) Invalidate ¶
func (r *DelegatedCredentialResolver) Invalidate(ctx context.Context, requirement authcfg.Requirement) error
Invalidate implements config.CredentialResolver. It deletes only the exact canonical-user/provider row. Unknown providers or a missing canonical owner must never delete credentials.
func (*DelegatedCredentialResolver) MaxRefreshLead ¶
func (r *DelegatedCredentialResolver) MaxRefreshLead(ctx context.Context) time.Duration
MaxRefreshLead implements DelegatedTokenRefresher.
func (*DelegatedCredentialResolver) Refresh ¶
func (r *DelegatedCredentialResolver) Refresh(ctx context.Context, requirement authcfg.Requirement) (*authcfg.Credential, error)
Refresh implements config.CredentialResolver. Per contract it bypasses any cached access token and mints a fresh credential while retaining the stored refresh credential.
func (*DelegatedCredentialResolver) RefreshStoredDelegatedToken ¶
func (r *DelegatedCredentialResolver) RefreshStoredDelegatedToken(ctx context.Context, stored *OAuthToken) error
RefreshStoredDelegatedToken implements DelegatedTokenRefresher for the background watcher. Unknown providers, malformed metadata and disabled providers are skipped without modifying stored credentials; provider failures are isolated to the row.
func (*DelegatedCredentialResolver) Resolve ¶
func (r *DelegatedCredentialResolver) Resolve(ctx context.Context, requirement authcfg.Requirement) (*authcfg.Credential, error)
Resolve implements config.CredentialResolver.
type DelegatedMCPAuth ¶
type DelegatedMCPAuth struct {
// contains filtered or unexported fields
}
type DelegatedTokenLister ¶
type DelegatedTokenLister interface {
ListDelegated(ctx context.Context, userID string) ([]*OAuthToken, error)
}
DelegatedTokenLister is the optional listing surface used by the user-lifecycle cleanup hook to enumerate a canonical user's delegated rows.
type DelegatedTokenRefresher ¶
type DelegatedTokenRefresher interface {
// RefreshStoredDelegatedToken applies the row's provider-specific refresh
// policy and, when due, refreshes through that provider's exact
// client/token endpoint using the distributed lease and CAS write.
RefreshStoredDelegatedToken(ctx context.Context, stored *OAuthToken) error
// MaxRefreshLead returns the largest configured provider refresh lead used
// as the watcher's broad scan horizon.
MaxRefreshLead(ctx context.Context) time.Duration
}
DelegatedTokenRefresher lets the background watcher refresh delegated rows through their exact provider broker. Until installed, delegated rows are skipped without mutation.
type DelegatedTokenStore ¶
type DelegatedTokenStore interface {
GetExact(ctx context.Context, userID, provider string) (*OAuthToken, error)
Put(ctx context.Context, token *OAuthToken) error
Delete(ctx context.Context, userID, provider string) error
TryAcquireRefreshLease(ctx context.Context, userID, provider, owner string, ttl time.Duration) (version int64, acquired bool, err error)
ReleaseRefreshLease(ctx context.Context, userID, provider, owner string) error
CASPut(ctx context.Context, token *OAuthToken, expectedVersion int64, owner string) (swapped bool, err error)
}
DelegatedTokenStore is the exact, canonical-user-keyed persistence surface used for delegated MCP credentials. It deliberately excludes the legacy fallback Get: delegated storage keys require exact matches and delegated owner resolution uses CanonicalUserID directly, never resolveOAuthTokenOwnerID.
type ExpiringTokenScanner ¶
type ExpiringTokenScanner interface {
// ScanExpiring returns all stored tokens whose expiry is before horizon
// and that carry a refresh token. Only tokens that can actually be
// refreshed need to be returned.
ScanExpiring(ctx context.Context, horizon time.Time) ([]*OAuthToken, error)
}
ExpiringTokenScanner is an optional extension of TokenStore for implementations that can efficiently query the store for tokens expiring before a given horizon. It is used by the background refresh watcher to proactively refresh tokens for users who are idle (no active in-memory session) before they expire. TokenStore implementations that do not embed a queryable DB may omit this.
type MCPAuthChangeEvent ¶
type MCPAuthChangeEvent struct {
// Kind is one of "linked", "disconnected".
Kind string
// CanonicalUserID keys credential storage and resolver cooldowns.
CanonicalUserID string
// EffectiveUserID keys the MCP manager client pool.
EffectiveUserID string
ServerName string
ProviderRef string
StorageKey string
}
MCPAuthChangeEvent describes a delegated MCP credential change (link, disconnect, invalid_grant). Subscribers evict caches only — the event never changes EffectiveUserID, sessions or the workspace provider.
type MCPAuthConfigProvider ¶
type MCPAuthConfigProvider interface {
Options(ctx context.Context, serverName string) (*mcpcfg.MCPClient, error)
}
MCPAuthConfigProvider yields MCP client configurations for the hosted link endpoints. The MCP manager's repository provider satisfies it; the runtime falls back to a workspace repository loader when none is installed.
type MCPAuthState ¶
type MCPAuthState struct {
CanonicalUserID string `json:"canonicalUserId"`
SessionIDHash string `json:"sessionIdHash"`
ServerName string `json:"serverName"`
ProviderRef string `json:"providerRef"`
ClientRef string `json:"clientRef,omitempty"`
Resource string `json:"resource,omitempty"`
Scopes []string `json:"scopes,omitempty"`
CodeVerifier string `json:"codeVerifier"`
ReturnURL string `json:"returnURL,omitempty"`
Nonce string `json:"nonce"`
ExpiresAt time.Time `json:"expiresAt"`
// ConfigFingerprint records the non-secret provider-registry fingerprint
// at initiation; the callback verifies the configuration has not changed
// underneath the flow.
ConfigFingerprint string `json:"configFingerprint,omitempty"`
// RedirectURI pins the exact redirect used on the authorization request so
// the token exchange sends the identical value.
RedirectURI string `json:"redirectURI,omitempty"`
}
MCPAuthState is the encrypted callback state payload for delegated MCP OAuth. It round-trips through the browser only as AEAD ciphertext; the database stores only its hash. The PKCE verifier lives exclusively here.
type MCPLinkBackend ¶
type MCPLinkBackend struct {
// contains filtered or unexported fields
}
MCPLinkBackend exposes the same provider registry, PKCE/state validation, grant verification and refresh lifecycle to hosts with their own ingress and storage. The stores may be local files; no native DB is required.
func NewMCPLinkBackend ¶
func NewMCPLinkBackend(cfg *Config, registry *providerregistry.Registry, tokens DelegatedTokenStore, states OAuthStateStore, configs MCPAuthConfigProvider, users UserService) (*MCPLinkBackend, error)
func (*MCPLinkBackend) Complete ¶
func (b *MCPLinkBackend) Complete(ctx context.Context, identity MCPLinkIdentity, code, state string) (*MCPLinkCompletion, error)
func (*MCPLinkBackend) Initiate ¶
func (b *MCPLinkBackend) Initiate(ctx context.Context, identity MCPLinkIdentity, server, returnURL, callbackURL string) (*MCPLinkInitiation, error)
func (*MCPLinkBackend) Invalidate ¶
func (b *MCPLinkBackend) Invalidate(ctx context.Context, identity MCPLinkIdentity, requirement authcfg.Requirement) error
func (*MCPLinkBackend) Refresh ¶
func (b *MCPLinkBackend) Refresh(ctx context.Context, identity MCPLinkIdentity, requirement authcfg.Requirement) (*authcfg.Credential, error)
func (*MCPLinkBackend) Resolve ¶
func (b *MCPLinkBackend) Resolve(ctx context.Context, identity MCPLinkIdentity, requirement authcfg.Requirement) (*authcfg.Credential, error)
func (*MCPLinkBackend) Status ¶
func (b *MCPLinkBackend) Status(ctx context.Context, identity MCPLinkIdentity, server string) (*MCPLinkStatus, error)
type MCPLinkCompletion ¶
type MCPLinkCompletion = mcpCallbackResult
type MCPLinkIdentity ¶
type MCPLinkIdentity struct{ CanonicalUserID, EffectiveUserID, SessionID string }
MCPLinkIdentity is a trusted host's already-authenticated identity and session binding. It must never be decoded directly from an HTTP/MCP body. Hosts resolve CanonicalUserID through their authoritative user service.
type MCPLinkInitiation ¶
type MCPLinkInitiation = mcpInitiateResult
type MCPLinkStatus ¶
type MCPLinkStatus = mcpStatusResult
type OAuth ¶
type OAuth struct {
Name string `json:"name,omitempty" yaml:"name,omitempty"`
Client *OAuthClient `json:"client,omitempty" yaml:"client,omitempty"`
}
type OAuthClient ¶
type OAuthClient struct {
Scopes []string `json:"scopes,omitempty" yaml:"scopes,omitempty"`
WebUIScopes []string `json:"webUIScopes,omitempty" yaml:"webUIScopes,omitempty"`
MobileUIScopes []string `json:"mobileUIScopes,omitempty" yaml:"mobileUIScopes,omitempty"`
CLIScopes []string `json:"cliScopes,omitempty" yaml:"cliScopes,omitempty"`
ConfigURL string `json:"configURL,omitempty" yaml:"configURL,omitempty"`
}
type OAuthStateRecord ¶
type OAuthStateStore ¶
type OAuthToken ¶
type OAuthToken struct {
Username string `json:"username"`
Provider string `json:"provider"`
AccessToken string `json:"accessToken"`
IDToken string `json:"idToken,omitempty"`
RefreshToken string `json:"refreshToken,omitempty"`
ExpiresAt time.Time `json:"expiresAt,omitempty"`
// Issuer is the normalized OAuth issuer the token was granted by.
Issuer string `json:"issuer,omitempty"`
// Resource is the protected resource (audience) the token targets.
Resource string `json:"resource,omitempty"`
// Scopes are the granted scopes (authoritative after refresh).
Scopes []string `json:"scopes,omitempty"`
// TokenType records accessToken versus idToken usage intent.
TokenType string `json:"tokenType,omitempty"`
// Subject is the provider subject extracted from the verified token; it is
// credential metadata only and never becomes the effective user.
Subject string `json:"subject,omitempty"`
// ProviderRef/ClientRef record the workspace provider registry references
// for delegated tokens (the row provider column stores a fixed-length
// hashed storage key).
ProviderRef string `json:"providerRef,omitempty"`
ClientRef string `json:"clientRef,omitempty"`
// IDTokenExpiresAt is the verified ID-token exp. ExpiresAt remains the
// access-token expiry for compatibility; tokenType=idToken consumers must
// derive validity and refresh thresholds from this field instead.
IDTokenExpiresAt time.Time `json:"idTokenExpiresAt,omitempty"`
// IssuedAt records when the token set was obtained (login, exchange or
// refresh); the refresh policy uses it to derive the original selected
// token lifetime for the 20% clamp.
IssuedAt time.Time `json:"issuedAt,omitempty"`
}
OAuthToken represents a stored OAuth token set for a user/provider pair. The metadata fields (Issuer, Resource, Scopes, TokenType, Subject, ProviderRef, ClientRef) are optional for backward compatibility with legacy workspace rows; delegated (per-provider MCP) tokens always populate them and every conversion/refresh path must preserve them.
func (*OAuthToken) HasDelegatedMetadata ¶
func (t *OAuthToken) HasDelegatedMetadata() bool
HasDelegatedMetadata reports whether the token carries the delegated credential metadata that refresh/CAS paths must not drop.
func (*OAuthToken) MergeMetadataFrom ¶
func (t *OAuthToken) MergeMetadataFrom(prior *OAuthToken)
MergeMetadataFrom copies missing metadata fields from prior. Populated fields on the receiver win (e.g. an authoritative refreshed scope set).
type PreferencesPatch ¶
type PreferencesPatch struct {
DisplayName *string `json:"displayName,omitempty"`
Timezone *string `json:"timezone,omitempty"`
DefaultAgentRef *string `json:"defaultAgentRef,omitempty"`
DefaultModelRef *string `json:"defaultModelRef,omitempty"`
DefaultEmbedderRef *string `json:"defaultEmbedderRef,omitempty"`
AgentPrefs map[string]map[string]interface{} `json:"agentPrefs,omitempty"`
}
PreferencesPatch describes a partial update to user preferences.
type Session ¶
type Session struct {
ID string `json:"id"`
UserID string `json:"userId,omitempty"`
Username string `json:"username"`
Email string `json:"email,omitempty"`
Subject string `json:"subject,omitempty"`
Provider string `json:"provider,omitempty"`
Scopes []string `json:"scopes,omitempty"`
Tokens *scyauth.Token `json:"-"`
// TransientRefreshRetryAt suppresses repeated refresh attempts/log spam
// after a temporary token-endpoint failure. Runtime auth code persists the
// cooldown through session metadata when a durable store is configured.
TransientRefreshRetryAt time.Time `json:"-"`
CreatedAt time.Time `json:"createdAt"`
ExpiresAt time.Time `json:"expiresAt"`
}
Session represents an authenticated user session.
Identity model:
- UserID = canonical agently users.id when available
- Subject = raw oauth/jwt subject
- Username = jwt.preferred_username or jwt.name — display name only
- Email = jwt.email — display / contact only
Identity split:
- sess.UserID is the canonical users.id UUID for internal persistence, token storage, token refresh, and session bookkeeping.
- request EffectiveUserID is the provider subject/email/username used by ownership and visibility filters, including created_by_user_id.
Do not feed sess.EffectiveUserID() into request context unless created_by_user_id has been migrated to canonical users.id. Token persistence can use the canonical UserID, but request-scoped ownership must remain subject-compatible.
func (*Session) EffectiveUserID ¶
EffectiveUserID returns the canonical session identity when available. This is intended for session/token persistence. For request-scoped ownership or visibility checks, use Subject/Email/Username directly; those filters still compare against subject-based created_by_user_id values.
type TokenStore ¶
type TokenStore interface {
Get(ctx context.Context, username, provider string) (*OAuthToken, error)
Put(ctx context.Context, token *OAuthToken) error
Delete(ctx context.Context, username, provider string) error
// TryAcquireRefreshLease atomically attempts to acquire a distributed lease
// for refreshing the token identified by (username, provider).
TryAcquireRefreshLease(ctx context.Context, username, provider, owner string, ttl time.Duration) (version int64, acquired bool, err error)
// ReleaseRefreshLease releases a previously acquired lease.
ReleaseRefreshLease(ctx context.Context, username, provider, owner string) error
// CASPut atomically updates the token only if the current version matches
// expectedVersion and the lease is held by owner.
CASPut(ctx context.Context, token *OAuthToken, expectedVersion int64, owner string) (swapped bool, err error)
}
TokenStore abstracts encrypted OAuth token persistence. Implementations may use scy-backed secrets, database storage, etc.
type User ¶
type User struct {
ID string `json:"id,omitempty"`
Username string `json:"username"`
Email string `json:"email,omitempty"`
DisplayName string `json:"displayName,omitempty"`
Provider string `json:"provider,omitempty"`
Subject string `json:"subject,omitempty"`
Preferences map[string]interface{} `json:"preferences,omitempty"`
// Disabled marks a deactivated canonical user: disabled users cannot use
// stored delegated credentials and fail canonical resolution.
Disabled bool `json:"disabled,omitempty"`
}
User represents a registered user.
type UserByIDLookup ¶
UserByIDLookup is the optional by-ID active-status lookup used by the delegated credential resolver, the background refresh watcher and the link endpoints: a disabled or deleted canonical user cannot use delegated tokens. It is a separate interface so existing UserService implementations remain compatible.
type UserInfo ¶
UserInfo carries host-provided profile identifiers. These values are token partitioning metadata and never substitute for an authorization provider.
func UserFromContext ¶
type UserService ¶
type UserService interface {
GetByUsername(ctx context.Context, username string) (*User, error)
GetBySubjectAndProvider(ctx context.Context, subject, provider string) (*User, error)
Upsert(ctx context.Context, user *User) error
UpsertWithProvider(ctx context.Context, username, displayName, email, provider, subject string) (string, error)
UpdateHashIPByID(ctx context.Context, id, hash string) error
UpdatePreferences(ctx context.Context, username string, patch *PreferencesPatch) error
}
UserService abstracts user CRUD. Implementations may use Datly, SQL, or an in-memory store.
Source Files
¶
- config.go
- context.go
- delegated.go
- delegated_key.go
- discovery.go
- events.go
- jwt_payload.go
- mcp_credential_resolver.go
- mcp_link_backend.go
- mcp_link_service.go
- mcp_oauth_callback.go
- mcp_oauth_state.go
- mcp_rate_limit.go
- mcp_token_response.go
- oauth_support.go
- preferences.go
- refresh_helpers.go
- session.go
- state_codec.go
- state_store.go
- string_helpers.go
- token_store.go
- user.go
Directories
¶
| Path | Synopsis |
|---|---|
|
internal
|
|
|
SPDX-License-Identifier: Apache-2.0 Extracted from Viant Agently Core.
|
SPDX-License-Identifier: Apache-2.0 Extracted from Viant Agently Core. |
|
Package providerregistry implements the workspace OAuth provider registry.
|
Package providerregistry implements the workspace OAuth provider registry. |