Skip to content

0.8.2

Choose a tag to compare

@watchlight-ai watchlight-ai released this 05 Sep 20:27
· 25 commits to main since this release
6703f86

The framework-plugin path can name an acting subject, and its Cedar entity types now discriminate. Both come from watchlight-agent-sdk 0.7.0, which the framework extras now require.

A subject, per call

async with await plugin.start_run("support-agent") as handle:
    ok = await handle.authorize_action(
        "read_ticket", "tool/read_ticket",
        principal=f'User::"{user_id}"',
        context={"caller": caller, "owner": owner},
    )

Omitted, the subject defaults to the agent that runs, so an existing call is unchanged. Previously there was no per-call principal at all on this path and every decision was attributed to the runtime.

governed_plugin() still refuses principal, context and resource at construction, because all three belong to a call rather than to the factory. Only the message changed: it now says where the term goes.

Entity types now discriminate on this path

The plugin path used to wrap each term in a Cedar type and then strip that wrapper straight back off before the engine saw it. The two halves cancelled, so every term arrived as a bare name, and a bare name matches every entity type with the same id.

The effect was that a policy written to admit only User::"u1" also admitted Agent::"u1". The entity-type distinction the identity model rests on was not enforced on this path.

Terms now reach the engine exactly as written. A typed reference discriminates. A bare name is still a wildcard across types, which is fine for a scratch policy and wrong for a decision you rely on, and the documentation now says so.

Breaking, for the plugin path only

A policy that names the agent with any type other than Agent:: goes from allow to deny, because it was previously matching a bare name that matched every type.

// before
permit(principal == User::"<agent uuid>", action == Action::"read", resource);
// after
permit(principal == Agent::"<agent uuid>", action == Action::"read", resource);

If you pass a typed resource string, its type must match the policy's. Every flip is in the closed direction; nothing becomes more permissive, and there is no transitional flag.

The SDK path, the tool() decorator and anything running against the networked control plane are unaffected.

Install

pip install "watchlight[pydantic-ai]==0.8.2"
npm install @watchlight/sdk@0.8.2

The TypeScript package is unchanged in this release and is versioned in step. The Python framework extras now require watchlight-agent-sdk>=0.7.