charter.auth, not charter.
Charter never acquires or stores credentials. A CredentialProvider is the seam
between the host application, which owns them, and the runtime, which needs a
bearer token for the length of one request.
A missing or rejected token raises
CredentialError; the runtime never
re-authenticates on its own.
Credentials
A bearer token, and optionally when it stops being valid.
str
required
The bearer token, sent as
Authorization: Bearer ....Optional[datetime]
When the token lapses.
None means the caller has not said, and the token is
treated as valid — the API is then the judge.Credentials.is_expired
expires_at minus leeway_seconds. Credentials with
no expires_at never report expired. A naive datetime is read as UTC, so a
provider handing back a naive timestamp is not treated as far-future or
far-past.
CredentialProvider
isinstance(obj, CredentialProvider) is a structural check on the method.
str
required
The identifier the tool was declared with —
"google", "slack". It names
the API, never the end user, so one implementation can serve several APIs. For
who a call acts as, see SubjectProvider.invalidate(credentials). It is not
part of the protocol, and is called only if present: when the API refuses a
token — a 401, or an envelope’s credential error — the runtime passes it the
credentials it sent, so the next call can fetch fresh ones. The refused call
still raises. A provider that holds nothing has nothing to drop and need not
define it.
StaticTokenProvider
CredentialError at construction. Its repr masks the token.
EnvTokenProvider
str
required
The variable to read. An empty name raises
CredentialError at construction;
an unset or empty variable raises CredentialError at call time, naming the
variable.CallbackProvider
CredentialError.
provider names the API, not the person: one of these serves one identity. For
many, see SubjectProvider; to refresh a grant rather than
read a stored token, see OAuth2Client.
SubjectProvider
OAuth2Client.
Callable[[str], CredentialProvider | Awaitable[CredentialProvider]]
required
Builds the provider for one subject. Sync or async. Returning
None raises
CredentialError naming the subject. A non-callable raises CredentialError
at construction.int
default:"1000"
How many built providers to keep, evicted least-recently-used. Below 1 raises
ValueError. Each provider carries its own cached token and refresh lock, so
eviction removes both together.Methods
Credentials
Resolves the current subject, then delegates. Concurrent cold starts for one
subject are single-flighted, so twelve simultaneous calls read your token
store once.
str
The subject for this call. Never falls back to a default or to whoever went
last: an unset subject raises
CredentialError naming what to do about it.None
Drop a subject’s provider — after a revocation, or a sign-out.
bool
Disconnect one subject. Builds their provider if it is not held (your
factory reads their stored grant, as for a tool call) and calls its
revoke() — OAuth2Client.revoke.
The subject is named rather than read from current_subject, since a
disconnect is a request about one user, not a tool call made as one.
Returns True when the server confirmed the revocation and False when the
grant was already gone. An OAuth2Client that reads your store through a
GrantLoader is kept afterwards: it refuses
the revoked grant while your store still holds it, so a call made in the
moment before you delete the row is not sent with it, and it takes up a new
grant as soon as one is stored. Any other provider is forgotten, and so is
one whose revocation raised, so the next lookup builds it from your store
again. A provider with no revoke(), such as StaticTokenProvider, raises
CredentialError pointing at revoke_token.
Deleting the stored grant is yours, afterwards.None
Pass a refused token on to the current subject’s provider. The provider, and
the grant it holds, are kept.
int
How many providers are currently held.
max_subjects
distinct other users inside one refresh, so raise the cap rather than tuning
around it.
current_subject
get_credentials(name) and knows nothing else.
A ContextVar is per-task in asyncio, so concurrent requests sharing one set of
tools cannot see each other’s subject. Set it directly with
current_subject.set(...) when you own the reset, or use the context manager
below.
use_subject
current_subject for the duration of a block. Resets on the way out,
including on an exception, so a failed request cannot leave its identity behind
for the next one. An empty subject raises CredentialError.
Related
- Authorization servers — declaring the server an
OAuth2Clientrefreshes against - The OAuth flow — obtaining the grant in the first place
OAuth2Client— the provider that renews a token