Documentation
¶
Overview ¶
Package scripttoken is the signed token a managed script mints and verifies (#2175): platform.token.mint and platform.token.verify. A token is an HMAC-SHA256 over a JSON body carrying the script's claims, the endpoints or the script it is bound to, its expiry, an id, and whether it may be used once. The key is derived from a stored secret the script names, and the script never sees the secret's value.
It is the same form the bot check's proof-of-work challenge is signed in (internal/botcheck), kept in-house rather than a JWT: the platform both mints and verifies, so nothing outside it has to read one.
Index ¶
Constants ¶
const ( CapabilityMint = "platform.mint_token" CapabilityVerify = "platform.verify_token" )
The platform members a script mints and verifies with.
const ( // MaxTokenLen bounds a token before anything is decoded from it. MaxTokenLen = 8192 // MaxClaimsBytes bounds the claims a script puts in one token. MaxClaimsBytes = 4096 // MaxTTL is the longest a token may live. MaxTTL = 30 * 24 * time.Hour // MaxEndpoints is the most endpoints one token may be bound to. MaxEndpoints = 16 )
Limits on what a token carries and how long it lives.
const ( ReasonMalformed = "malformed" ReasonTampered = "tampered" ReasonExpired = "expired" ReasonOtherEndpoint = "other_endpoint" ReasonUsed = "used" )
Reasons a token is refused, as verify returns them to the script.
const SecretUse = "script_token"
SecretUse is the name a token key's allow_connections lists: a token key is never sent through a connection, so the reserved name is what scopes a stored secret to this use, as botcheck.SecretUse does for a provider key.
Variables ¶
var ErrRefused = errors.New("token refused")
ErrRefused is the error every refusal wraps; Reason reads which it was.
Functions ¶
Types ¶
type Authority ¶
Authority resolves the persona roles act as and whether it is the administrator's, the resolution a run's own session gets from the persona layer.
type Binding ¶
Binding is where a token is minted or verified: inside an endpoint request, the endpoint's name; anywhere else, the script.
type Caller ¶
type Caller interface {
CallTool(ctx context.Context, name string, args map[string]any) (map[string]any, error)
}
Caller answers one mint or verify, named by its capability, with the arguments the script passed: an Issuer in a run, the recording in a test.
type Host ¶
type Host struct {
// Ctx is the run's context.
Ctx context.Context //nolint:containedctx // the run's lifetime, which both members read
// Testing is a test or a replay: calls go to Replay.
Testing bool
// Replay answers a test's calls, from the recording or a declared answer.
Replay Caller
// Live answers a run's calls; nil where this deployment issues no tokens.
Live Caller
// Record records a run's call and its answer, nil when nothing records.
Record func(tool string, args, out map[string]any, err error)
}
Host is the two members as a run binds them, the way scriptpace.Clock binds remaining_ms: in a run each call goes to Live and is recorded, and in a test it is answered from the recording, so a test of a handler that mints or verifies needs neither the key nor the database.
func (Host) Mint ¶
func (h Host) Mint(_ *starlark.Thread, b *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error)
Mint is platform.mint_token(claims, ttl, secret, endpoints=None, single_use=False): the token, as a string.
func (Host) Verify ¶
func (h Host) Verify(_ *starlark.Thread, b *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error)
Verify is platform.verify_token(token, secret): a dict whose "ok" says whether the token holds, with its "claims" when it does and the "reason" it was refused for when it does not, so a script answers a refusal itself.
type Issuer ¶
type Issuer struct {
Keys KeyReader
Uses Uses
// Authority resolves a run's roles to its persona; nil resolves none, so
// only a key naming no personas can be used.
Authority Authority
// Now is the clock; nil is time.Now.
Now func() time.Time
}
Issuer answers a run's mints and verifies: the deployment's secrets and single-use record, and Bind's per-run identity.
type KeyReader ¶
KeyReader reads a stored secret's value for this use, refusing a secret whose allow_connections does not list SecretUse or whose allow_personas does not name persona (the administrator's is unrestricted).
type Mint ¶
type Mint struct {
Claims map[string]any
TTL time.Duration
// Endpoints names the endpoints the token verifies at; empty binds it to
// where it was minted.
Endpoints []string
SingleUse bool
}
Mint is one token's request.
type PostgresUses ¶
type PostgresUses struct {
// contains filtered or unexported fields
}
PostgresUses is Uses over the script_token_uses table.
type Uses ¶
type Uses interface {
// Use records the token's id until it expires and reports whether this
// was its first use.
Use(ctx context.Context, id string, expires time.Time) (bool, error)
// Sweep deletes the records of tokens that have expired.
Sweep(ctx context.Context, now time.Time) (int64, error)
}
Uses records the single-use tokens that have been verified, so a second use is refused on every replica.