"Always allow" approvals of a ConduitMcp.Client (PO-10, PO-11).
When ConduitMcp.Client.Policy decides :ask for a call, the client's
:on_ask approver is called (see ConduitMcp.Client.Pipeline). An answer
of {:allow, :always} records a grant keyed
{principal, server_id, tool_name, fingerprint}that answers the same question for :grant_ttl (default 24 hours)
without asking again:
principalis the call's:principaloption (the end user the host acts for;nilwhen not given), so one user's grant never applies to another (PO-10). Without principals, grants are per client.fingerprintis the tool'sConduitMcp.Client.Fingerprintwhen it was approved: a server that changes the tool's definition gets asked about again (PO-6).
A grant only settles an :ask. It never overrides a deny rule, and it
marks the tool's current fingerprint as approved for that principal, so
the policy's pin (pin_tools) and allow_new_tools checks treat the
tool as known.
Grants live in the client's governance table: :protected ETS owned by a
process under the client's supervisor, read directly by callers and
written only by that process. They are lost when the client restarts
(which only means asking again).
Summary
Functions
Removes every grant.
The client's unexpired grants. expires_at is Unix time in milliseconds
(from the client's :clock).
Removes every grant of principal.
Types
Functions
@spec clear(term()) :: :ok | {:error, ConduitMcp.Client.Error.t()}
Removes every grant.
@spec list(term()) :: {:ok, [grant()]} | {:error, ConduitMcp.Client.Error.t()}
The client's unexpired grants. expires_at is Unix time in milliseconds
(from the client's :clock).
@spec revoke(term(), term()) :: :ok | {:error, ConduitMcp.Client.Error.t()}
Removes every grant of principal.