Skip to Content
Policy handshake

Policy handshake

Roadmap

This capability is on the Roadmap; the API shown here is the planned design. It depends on a policy-discovery endpoint on the gateway, which does not exist today.

On first connection, DDK will fetch the policy set in force for your credentials and expose it:

donkey.policies.models_allowed # ["gpt-4o", "claude-sonnet"] donkey.policies.tools_allowed # [...] donkey.policies.budget # the same Budget object, now live donkey.policies.pii.mode # "block" | "mask" | "log" donkey.policies.content_safety.on # True donkey.policies.observed_at # when this view was fetched

What it enables

Fewer wasted calls. An agent that requests a model outside its allow-list costs one round-trip and one refusal, every time. With the handshake, the adapter picks from models_allowed at construction time and the refusal never happens. Multiply by a few thousand tickets a day.

Better UX. If pii.mode == "mask", the gateway will redact rather than reject — so your bot can say “some details were redacted” instead of “request failed.” Same gateway behaviour, a very different experience, and today the client has no way to know which mode is in force.

Warm start. It also makes budget live rather than last-known-good: a fresh process currently knows nothing about its budget until its first response comes back.

The handshake is advisory

The handshake never makes an access decision. It exists to avoid wasted calls and to improve UX. The gateway still evaluates every request.

If the client’s cached view and the gateway disagree, the gateway wins and the client learns from the refusal. Skipping a gateway call “because the handshake said it’s fine” is client-side enforcement, which is on the will-not-build list.

This is also why observed_at is part of the surface, as it is on the budget object: a policy view is a snapshot, and code that cannot tell a snapshot from live state will eventually make a decision it should not have.

Last updated on