Onyx Gate for Drata
File verifiable AI-agent authorization evidence into Drata. An Onyx gateway decides every agent tool call against policy and appends each decision — full call arguments, allow/deny verdict, policy version, optional machine-checkable certificate — to a hash-chained audit trail. This bridge re-verifies that trail's integrity independently (pure Python, no engine, no dependencies) and files it as Drata Evidence linked to your controls, with a report that tells the auditor exactly how to re-check everything themselves.
That last part is the point. Most AI-governance evidence is a screenshot or an export — the auditor trusts whoever produced it. This trail is evidence an auditor can re-derive: the chain rule is fifteen lines of any language, and the decision certificates re-check against the engine's proof kernel.
Onyx gateway ──--log──▶ trail.jsonl ──verify + package──▶ Drata Evidence
(decides every hash-chained onyx-gate-drata linked to
agent tool call) JSONL (this bridge) your controls
What it looks like
verify re-checks a trail offline — here against a real gateway session
(an accounts-payable agent whose $12,000 out-of-mandate payment was denied):
$ onyx-gate-drata verify crewai-session.trail.jsonl
8 record(s): 6 allow / 2 deny, 4 with certificates; chain: 8 linked, 0 unchained, 0 broken
chain head: 0a91713a091d6c78f1b6ea1256d9f939303fbf49a5be5e3910d0d9fde2a88195
chain: VERIFIED
Edit one byte — quietly changing the denied amount from 12000 to 900 — and:
8 record(s): 6 allow / 2 deny, 4 with certificates; chain: 7 linked, 0 unchained, 1 broken
record 5: broken — recorded link 2ea6e5fe791f8a10… does not match the expected
3c03da7eec5e6980… — the previous record was edited, deleted, or reordered
chain: FAILED (exit 1)
This verifier is deliberately independent of the engine — and agrees with
it hash-for-hash: on the trails above, the engine's own checker (eg_verify --audit-log) reports the identical chain head on the valid trail and the
identical broken link (same recorded/expected hashes) on the tampered one.
Two implementations, two codebases, one verdict.
file verifies and then files — fail-closed: a trail that does not verify
is never filed, and nothing touches the network on refusal:
$ onyx-gate-drata file crewai-session.trail.jsonl --workspace-id 7 --control-ids 17,42
filed: evidence 4242 in workspace 7 ('Onyx decision trail — crewai-session')
linked controls: [17, 42]
chain head anchored in the evidence description: 0a91713a091d6c78…
Two artifacts land on the Evidence item: the verbatim trail bytes
(uploaded as .log — a rename for Drata's accepted types, the bytes
untouched so the hashes still verify) and a Markdown verification report:
the verdict, the decision summary, every deny with its policy reason, the
chain head to anchor, and the independent re-check instructions.
Setup
pip install onyx-gate-drata # standard library only
- Drata side: create an API key (Drata scopes keys per endpoint — this
tool needs only the evidence write scope) and note your workspace id and
the control ids to link (e.g. your AI-governance / access-control controls).
Set
DRATA_API_KEYor pass--api-key-file;--region us|eu|apacselects the API base.--dry-runwrites the evidence bundle locally with no network calls, so you can inspect exactly what would be filed. - Onyx side: run the gateway with
--log trail.jsonl. Every integration writes the same trail — the CrewAI tool guard, the Obot MCP Gateway filter, the Claude Code enforcement hook, or direct HTTP/MCP calls. - Schedule
file(cron, CI, a workflow) for recurring evidence: each filing carries the current chain head, so consecutive filings chain into each other — a later trail that doesn't extend the last anchored head is visible.
The chain rule (the whole thing)
The first record's chain field must equal
SHA256("onyx-audit-trail-genesis-v1") in lowercase hex; every later
record's chain must equal the SHA-256 of the previous line's exact bytes.
That's it — auditors don't need this package, just any language's SHA-256.
import hashlib, json
expected = hashlib.sha256(b"onyx-audit-trail-genesis-v1").hexdigest()
for line in open("trail.jsonl", "rb").read().splitlines():
assert json.loads(line)["chain"] == expected, "chain broken"
expected = hashlib.sha256(line).hexdigest()
print("verified; head:", expected)
Scope, honestly
- The chain detects edits, deletions, and reordering within the file — it cannot detect truncation of the tail or deletion of the whole file. That is what anchoring the chain head outside the file is for, and filing it into Drata is exactly such an anchor.
- Chain integrity ≠ decision correctness. The chain proves these are the
decisions the gateway made; the certificates embedded in records address
correctness against the policy in force, and this tool only counts them —
they re-check with the engine's kernel (
eg_verify --audit-log), which the filed report points the auditor at. - Certificates are kernel-re-checkable records of the policy reasoning — not digital signatures.
- The Drata client covers the two evidence endpoints this bridge needs (per Drata's published API v2 spec), nothing more.
Getting the gateway
This bridge, the chain rule, and the test suite (which runs against real
committed trails and a scripted Drata stub) are Apache-2.0 and engine-free.
The gateway that writes the trails (eg_gateway) and the certificate
checker (eg_verify) are part of the Onyx engine — a verification-first
policy engine whose decision calculus is machine-checked in two independent
proof assistants — currently in design-partner preview.
Standing up AI-agent governance evidence for SOC 2 / ISO / your framework? contact@onyxfoundry.ai · onyxfoundry.ai
License
Apache-2.0. Drata is a trademark of Drata Inc.; this is an independent integration, not affiliated with or endorsed by Drata.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file onyx_gate_drata-0.1.0.tar.gz.
File metadata
- Download URL: onyx_gate_drata-0.1.0.tar.gz
- Upload date:
- Size: 21.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bcf5891baf9622e521c8ec3d42e0901c54063aa3a2993fafb1b0fea2ac727e77
|
|
| MD5 |
ecf890068da50225d7a02180936b8bc5
|
|
| BLAKE2b-256 |
db4bd82b7bbc64613f229fa46690e77f3dee6a3dcede0e3cced3ee23a04d2555
|
Provenance
The following attestation bundles were made for onyx_gate_drata-0.1.0.tar.gz:
Publisher:
release.yml on jstewart-axyom/onyx-gate-drata
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
onyx_gate_drata-0.1.0.tar.gz -
Subject digest:
bcf5891baf9622e521c8ec3d42e0901c54063aa3a2993fafb1b0fea2ac727e77 - Sigstore transparency entry: 2628010538
- Sigstore integration time:
-
Permalink:
jstewart-axyom/onyx-gate-drata@fb29e6f2c8d8e8c9faeb23dfa466ada960cb337f -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/jstewart-axyom
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@fb29e6f2c8d8e8c9faeb23dfa466ada960cb337f -
Trigger Event:
push
-
Statement type:
File details
Details for the file onyx_gate_drata-0.1.0-py3-none-any.whl.
File metadata
- Download URL: onyx_gate_drata-0.1.0-py3-none-any.whl
- Upload date:
- Size: 18.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
41fdee6126b6bedf440d1726c7485300c56d406399e9b6d479d7f25cb0113f9c
|
|
| MD5 |
94f507b5ebea3b0752b703ab06d8e52c
|
|
| BLAKE2b-256 |
82968ce5cfa5298603a50e62448662426c1389cb42cc25862a8000a0152cc613
|
Provenance
The following attestation bundles were made for onyx_gate_drata-0.1.0-py3-none-any.whl:
Publisher:
release.yml on jstewart-axyom/onyx-gate-drata
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
onyx_gate_drata-0.1.0-py3-none-any.whl -
Subject digest:
41fdee6126b6bedf440d1726c7485300c56d406399e9b6d479d7f25cb0113f9c - Sigstore transparency entry: 2628010544
- Sigstore integration time:
-
Permalink:
jstewart-axyom/onyx-gate-drata@fb29e6f2c8d8e8c9faeb23dfa466ada960cb337f -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/jstewart-axyom
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@fb29e6f2c8d8e8c9faeb23dfa466ada960cb337f -
Trigger Event:
push
-
Statement type: