Skip to main content

assurance-authority

tests PyPI License

An agent must not become a way to read things you cannot read

Give an agent a task that needs context above your clearance and there are three honest outcomes. It fetches the context as someone else and hands you the answer — which is a permission-laundering machine with your company's name on it. It refuses. Or the task changes owner, and the answer goes to the person who was always allowed to have it.

Only the last two are acceptable, and the rule that separates them is one function:

Context acquisition never raises the initiating principal's effective authorisation. Another principal's clearance may move the task. It may never move the answer.

This package makes that rule runnable against your own people and your own tasks.

Try it before you write anything

You need a declaration of your own principals before this can say anything about your team, and having nothing to point a tool at is a worse first run than a wrong answer. So there is one that needs no file:

pip install assurance-authority
assurance-authority --example

Real output, one declaration, three outcomes — and the middle one is the whole product.

1 of 3 tasks may proceed for the person who asked — 1 moved owner — 1 refused

  team roster      priya           proceed
  Q3 margin memo   priya           escalate_ownership  -> CFO
      Priya (intern) may not receive finance-confidential, and CFO may. The task moves to CFO
      rather than the answer moving to Priya (intern).
  payroll extract  drafting-agent  refuse
      Drafting agent may not receive payroll, and nobody offered can. The task stops here.

Then make it yours. This writes the declaration that produced the output above, and refuses to overwrite anything already there:

assurance-authority --example --write team.json
assurance-authority team.json

The intern asks for a margin memo. She may not have it; the CFO may. So the task moves to the CFO. She is told it moved. She is never told the figure. The alternative — an agent fetching it as a service account and handing her the answer — is a permission-laundering machine with your company's name on it, and it is what most systems do by default.

An agent asks for payroll. Nobody declared may own it, so it stops. Not downgraded to a summary, not answered with a subset.

Somebody asks for what they are cleared for. It proceeds, silently, which is the point.

As a gate

assurance-authority team.json --fail-on-escalation   # exit 1 if any task can't reach its asker

Useful when a clearance change quietly breaks a workflow: the task still completes, by someone else, and nobody notices until the person who used to get the answer asks why they stopped receiving it.

This is not for you if

  • You work alone. There is no permission model to preserve, so every task proceeds and the tool tells you nothing. This is for whoever is accountable when somebody else's agent reads something it should not have.
  • You want enforcement at runtime. This is a review of declared tasks against declared clearances. Enforcing it inside your agent loop is the library — assurance_core.principal — and that is where the rule actually lives.
  • Your clearances are not expressible as labels. It compares opaque sets and never interprets them. A rule like "only during market hours" is not something it can hold.

Thirty seconds

pip install assurance-authority
assurance-authority team.json

On a system Python you may hit error: externally-managed-environment (PEP 668). That is your OS protecting its packages, not this failing: python3 -m venv .venv && .venv/bin/pip install assurance-authority

2 of 5 tasks may proceed for the person who asked — 2 moved owner — 1 refused

  team roster       intern-42    proceed
  Q3 margin memo    intern-42    escalate_ownership -> CFO
  pipeline summary  analyst-7    proceed
  board pack        analyst-7    escalate_ownership -> CFO
  payroll extract   agent-a      refuse

The intern gets the roster. The margin memo moves to the CFO rather than the answer moving to the intern. The agent's payroll request is refused, because nobody declared may own it — not silently downgraded, not answered with a subset.

The declaration

One JSON file. Labels are opaque strings: your own scheme, a Sharepoint group id, whatever your identity system reports. Nothing here interprets them, it only compares sets.

{
  "principals": [
    {"id": "intern-42", "name": "Priya (intern)", "may_receive": ["general"]},
    {"id": "cfo-1",     "name": "CFO",            "may_receive": ["general", "finance-confidential"]}
  ],
  "tasks": [
    {"name": "Q3 margin memo", "initiator": "intern-42", "requires": ["finance-confidential"]}
  ]
}

As a library

from assurance_authority import loads, review

declaration = loads("""
{
  "principals": [
    {"id": "intern-42", "name": "Priya", "may_receive": ["general"]},
    {"id": "cfo-1",     "name": "CFO",   "may_receive": ["general", "finance-confidential"]}
  ],
  "tasks": [
    {"name": "Q3 margin memo", "initiator": "intern-42", "requires": ["finance-confidential"]}
  ]
}
""")

result = review(declaration)
row = result.rows[0]

assert row.resolution.resolution.value == "escalate_ownership"
assert row.delivered is False          # the answer does NOT go back to the intern
assert row.new_owner == "CFO"          # the task does

In a pipeline

assurance-authority team.json --fail-on-escalation
exit means
0 reviewed, and every task may proceed for the person who asked
1 reviewed, and --fail-on-escalation found a task that cannot be delivered to its initiator
2 refused — the declaration could not be read, so there is no review

2 is separate from 1 on purpose. "I could not answer" and "I answered and you will not like it" are different facts, and a pipeline that treats them the same will one day treat a broken config as a policy violation, or worse, the reverse.

What it refuses to do

  • A task whose initiator is not declared. Assuming an empty clearance would produce a refusal indistinguishable from a real one.
  • A task that requires nothing. That is not an authority question, and answering it would imply one had been asked.
  • Two clearances for one principal id. That is a question about which is real, and this cannot answer it.

As an agent skill

skills/task-clearance/ — drop it in and an agent checks clearance before it fetches anything on somebody's behalf. Its real content is that an escalation is not a failure: an agent reporting "3 of 5 tasks failed" when two correctly changed owner has described a healthy access model as a broken one.

Where the rule actually lives

assurance_core.principal.resolve, in assurance-core. This package reads a file, calls it once per task, and counts the answers. The arithmetic is deliberately thin so there is exactly one implementation of the thing that must never be wrong — and you can read it in one sitting to confirm no branch returns PROCEED on the strength of somebody else's clearance.

Licence

Apache-2.0.

Metadata

Release files for assurance-authority 0.1.4

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for assurance-authority 0.1.4
File Size Uploaded
assurance_authority-0.1.4.tar.gz 22.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for assurance-authority 0.1.4
File Interpreter ABI Platform
assurance_authority-0.1.4-py3-none-any.whl Python 3 none any Details

Total release size: 41.0 kB

Release files / assurance_authority-0.1.4.tar.gz

Download URL assurance_authority-0.1.4.tar.gz
Size 22.9 kB
Tags Source
SHA-256 checksum
How to use checksums
4a9cdcdc5da719ed7f401e13db8c183c64cfeacd9495c670e909438ccffca496
BLAKE2b-256 checksum
How to use checksums
b57a2d0c47f2e81720cee51a6ae1cb15ab72084324b94ea89e03e4f85be723ef
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 24, 2026.

Transparency log

Release files / assurance_authority-0.1.4-py3-none-any.whl

Download URL assurance_authority-0.1.4-py3-none-any.whl
Size 18.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ccb42e24d0b305778942e57a1af3b3a6034f507c16c1f0f3d6d731503adc7ada
BLAKE2b-256 checksum
How to use checksums
39e3609909f8a8f6633df0d228541efb5886bf048e819c1d4371f3ea9c0c73d6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 24, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.4 This release

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page