Skip to content

intent_bridge classifies malformed decision values as valid denial #319

Description

@altrudev

Problem

schema/pic-trace-bridge-v1.json restricts authorization.decision to exactly "allow" or "deny", but intent_bridge.verify_bridge() does not establish that enum at runtime before classifying the decision.

Current verifier logic is effectively:

if authorization["decision"] != "allow":
    raise AuthorizationDenied("the signed decision is not allow")

That means any correctly signed value other than the literal string "allow" is reported as AuthorizationDenied, including malformed values such as:

true
1
null
""
"reject"

Those values are not valid bridge decisions under the published schema. They should therefore be rejected through the bridge's malformed-input boundary, not represented as though the authorizer issued a legitimate signed denial.

Why the distinction matters

AuthorizationDenied means the bridge carried a valid authorization decision whose outcome was denial. IntentBridgeError is the module's malformed/untrusted/cannot-evaluate boundary. Conflating the two changes the fact reported to a caller and can route malformed producer output as a policy denial instead of a format defect.

This is also a schema/runtime consistency issue: a document rejected by the bridge schema can currently reach a semantic denial result in the direct runtime verifier.

Reproduction direction

Start from the existing valid fixture in tests/test_intent_bridge.py, replace only authorization.decision with each malformed value, re-sign the exact modified authorization using sign_bridge(), then call verify_bridge() at a valid fixed verification time.

Expected invariant:

  • "allow" -> existing success path;
  • "deny" -> AuthorizationDenied;
  • any other primitive/value -> malformed bridge refusal, not AuthorizationDenied.

The re-sign step matters so the decision check, rather than signature failure, is load-bearing.

Proposed bounded direction

Establish the decision enum explicitly before applying allow/deny semantics. Preserve the existing AuthorizationDenied behavior for the literal valid "deny" value.

No wire-format, schema, signature, scope, digest, transcript, or authorization-policy change is required.

I searched the current TRACE issue tracker for an existing issue covering this exact decision-enum/runtime-classification boundary and did not find one.

AI-assistance disclosure: ChatGPT assisted with repository triage, duplicate search, reproduction design, and issue drafting. altrudev reviewed the bounded claim and remains responsible for the contribution.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs-review:HIGHContributor check flagged HIGH risk

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions