Skip to content

Commit e21526b

Browse files
authored
Merge pull request #7 from barbacane-dev/update/fips-provenance-compliance
Add FIPS 140-3, config provenance, and drift detection
2 parents 2a8bd7b + 685cac3 commit e21526b

3 files changed

Lines changed: 383 additions & 1 deletion

File tree

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
---
2+
title: "Compliance by design, part 1: how Barbacane becomes your API audit trail"
3+
description: "Auditors don't just ask whether you have security controls. They ask how you can prove those controls were actually enforced. Explore how Barbacane's compiled approach turns your API gateway into a verifiable compliance artifact."
4+
publishDate: 2026-02-18
5+
author: "Baptiste Betelu"
6+
tags: ["barbacane", "api-gateway", "compliance", "security", "audit", "soc2", "pci-dss", "policy-as-code"]
7+
---
8+
9+
*Auditors don't ask whether you have access controls. They ask how you can prove those controls were enforced, consistently, on every request, across every environment.*
10+
11+
The gap between those two questions is where most API teams suffer during audits.
12+
13+
You can point to your OpenAPI spec. You can point to your gateway configuration. You can point to your authorization policies. But if those three artifacts live in three different places and are maintained by three different teams, the auditor's next question is: "How do you know they all say the same thing?" And the honest answer is: you hope they do.
14+
15+
Barbacane changes this. Not through a compliance dashboard or a report generator, but through its architecture. When your spec *is* your gateway, the gap between documentation and enforcement disappears. And when there's no gap, proving conformity becomes straightforward.
16+
17+
---
18+
19+
### The evidence problem
20+
21+
Compliance frameworks, whether SOC 2 Type II, PCI DSS, HIPAA, or ISO 27001, share a common requirement: you must demonstrate that your controls were actually applied, not just that you intended them to be.
22+
23+
For API gateways, that typically means gathering evidence from several disconnected places:
24+
25+
- The OpenAPI spec (what the API is *supposed* to do)
26+
- The gateway configuration (how the gateway is actually configured)
27+
- Code review history (what was approved)
28+
- Runtime logs (what actually happened)
29+
- Policy documents (what the rules are supposed to be)
30+
31+
The problem is that none of these sources are authoritative for the others. Your spec might say `GET /records` requires a JWT with a `records:read` scope. Your gateway might have been configured with that plugin, then reconfigured during a late-night hotfix. Your logs might show the endpoint responding successfully to requests that lacked the required scope. And nobody connects these dots until an auditor sits down with all three documents at once.
32+
33+
This is the configuration drift problem, and it turns every compliance audit into an investigation.
34+
35+
---
36+
37+
### Proof by artifact
38+
39+
Barbacane's compilation model flips this. When you run:
40+
41+
```bash
42+
barbacane compile \
43+
-s api.yaml \
44+
-m barbacane.yaml \
45+
-o api.bca
46+
```
47+
48+
The output is not just a gateway binary. It's a compliance artifact. Everything that the gateway will enforce, every route, every middleware, every authentication requirement, every authorization rule, is locked into that `.bca` file at compile time. The spec you review in a pull request is compiled into the artifact that runs in production. There is no separate configuration layer that could diverge from what was approved.
49+
50+
What this means for evidence gathering:
51+
52+
| Question | Traditional Answer | Barbacane Answer |
53+
|---|---|---|
54+
| What auth is enforced on this endpoint? | Read the gateway config (if you can find it) | Read the spec: the `x-barbacane-middlewares` entry is what ran |
55+
| Was this endpoint protected last quarter? | Dig through config history | Check the artifact version deployed that quarter |
56+
| Who approved the current access controls? | Find the ticket, find the review | The spec PR that changed the middleware config |
57+
| What was actually running in production? | Hope it matches the config that matches the spec | The compiled artifact. That's it. |
58+
59+
The artifact is the single source of truth. You can hash it, version it, store it in artifact registries, and attach it to change tickets. When an auditor asks "what was enforced on the `/payments` endpoint on November 3rd?", you pull the artifact that was deployed that day and read the spec it was compiled from.
60+
61+
Barbacane reinforces this with **artifact fingerprinting and build provenance**. Every compiled artifact contains a SHA-256 `artifact_hash` — a combined hash of all inputs (specs, plugins, configuration). You can also embed the Git commit SHA and build source directly into the artifact:
62+
63+
```bash
64+
barbacane compile \
65+
-s api.yaml \
66+
-m barbacane.yaml \
67+
-o api.bca \
68+
--provenance-commit $(git rev-parse HEAD) \
69+
--provenance-source ci/github-actions
70+
```
71+
72+
This provenance metadata is embedded in the artifact manifest. At runtime, you can query it via the dedicated admin API (a separate listener on port 8081, isolated from user traffic):
73+
74+
```
75+
GET /provenance
76+
```
77+
78+
The response includes `artifact_hash`, `compiled_at`, `compiler_version`, the source specs, bundled plugins, and whether drift has been detected. The admin port also serves health checks and Prometheus metrics, all separated from production traffic. This is the kind of structured, machine-readable evidence that auditors and compliance tools can consume directly — no spreadsheet required.
79+
80+
The gateway also serves the compiled specs at `/__barbacane/specs` — stripped of internal extensions, clean OpenAPI and AsyncAPI. Developer portals that pull from this endpoint always show the spec that corresponds to the running gateway. There is no publishing step that someone might forget, and the artifact hash links every served spec to a specific build.
81+
82+
#### Continuous drift detection
83+
84+
Even with immutable artifacts, a compliance concern remains: how do you know every data plane is actually running the artifact you deployed? Barbacane's control plane solves this with automatic drift detection. Each data plane reports its `artifact_hash` in WebSocket heartbeats (every 30 seconds). The control plane compares the reported hash against the expected artifact and flags any mismatch — with an amber warning in the Web UI, a `drift_detected` flag on the `/provenance` endpoint, and a warning log on the data plane itself.
85+
86+
For SOC 2 CC7.2 and ISO 27001 A.12.4, this provides evidence that your fleet is running the approved configuration — not just that you deployed it once and hoped for the best. When an auditor asks "how do you know all nodes were running the same policy last Tuesday?", the answer is a heartbeat log showing hash verification every 30 seconds.
87+
88+
---
89+
90+
### Access controls that live in the spec
91+
92+
One of the most common compliance requirements is demonstrating that sensitive endpoints have documented, enforced access controls. The conventional approach is to maintain a spreadsheet mapping endpoints to roles, then separately verify that the gateway configuration matches. This is manual, error-prone, and stale by the time anyone looks at it.
93+
94+
In Barbacane, the access control *is* the specification:
95+
96+
```yaml
97+
paths:
98+
/patients/{id}/records:
99+
get:
100+
summary: Retrieve patient records
101+
x-barbacane-middlewares:
102+
- name: jwt-auth
103+
config:
104+
issuer: "https://auth.example.com"
105+
required_claims:
106+
scope: "records:read"
107+
- name: cel
108+
config:
109+
expression: >
110+
'clinician' in request.claims.roles ||
111+
request.claims.sub == request.path_params.id
112+
deny_message: "Access restricted to treating clinicians and the patient"
113+
114+
delete:
115+
summary: Delete patient records
116+
x-barbacane-middlewares:
117+
- name: jwt-auth
118+
config:
119+
issuer: "https://auth.example.com"
120+
- name: cel
121+
config:
122+
expression: "'records-admin' in request.claims.roles"
123+
deny_message: "Deletion requires records-admin role"
124+
```
125+
126+
This is not documentation. This is configuration. The CEL expressions compiled from these annotations are what execute on every request. If the spec says `DELETE` requires the `records-admin` role, the gateway enforces that check. There is no step where someone might forget to update the middleware to match the documentation.
127+
128+
For a reviewer, the access control surface is entirely visible in the spec. You can see, in a single pull request, exactly what changed: what endpoint, what role requirement, what expression. The PR *is* the change management record.
129+
130+
---
131+
132+
### Authorization decision logs
133+
134+
For frameworks that require audit trails of access decisions (SOC 2 CC6.3, PCI DSS Requirement 10, HIPAA §164.312(b)), OPA integration provides something that CEL inline expressions alone cannot: a structured log of every authorization decision.
135+
136+
As we covered in our [authorization post](/blog/authorization-at-the-gateway/), when the OPA plugin is used, the gateway sends request context to your OPA deployment and enforces the boolean decision. But OPA also generates decision logs for every evaluation:
137+
138+
```json
139+
{
140+
"decision_id": "9f73d5d0-91a5-4f62-a6a3-7e3c4b1a2f8d",
141+
"timestamp": "2026-02-18T14:32:01.023Z",
142+
"input": {
143+
"method": "DELETE",
144+
"path": "/patients/pt-9142/records",
145+
"client_ip": "10.0.1.42",
146+
"claims": {
147+
"sub": "user-alice",
148+
"roles": ["clinician"],
149+
"iss": "https://auth.example.com"
150+
}
151+
},
152+
"result": false,
153+
"policy": "patients.records.delete"
154+
}
155+
```
156+
157+
This log entry answers the exact question auditors ask: *who requested what, when, with what credentials, and was it allowed?* Not inferred from application logs. Not reconstructed from access patterns. Explicitly recorded by the policy engine at the moment of the decision.
158+
159+
For compliance teams, this is the difference between "we believe we denied unauthorized deletions" and "here are 47,000 log entries showing every authorization decision made on this endpoint in Q4, with the specific policy that evaluated each one."
160+
161+
You can ship these logs to Datadog, Splunk, or any SIEM. The OPA decision log format is structured JSON, purpose-built for querying.
162+
163+
---
164+
165+
### What's next
166+
167+
This post covered the architectural foundations: how Barbacane's compilation model, artifact provenance, and drift detection turn the evidence problem into a solved problem. But there's more to the compliance story — schema validation as a data control boundary, secrets management, FIPS 140-3 cryptography, and how GitOps becomes your change management process.
168+
169+
We'll cover all of that in [Part 2: the compliance controls](/blog/compliance-by-construction-part-2/).
170+
171+
---
172+
173+
*Barbacane is open source (Apache 2.0) and available at [github.com/barbacane-dev/barbacane](https://github.com/barbacane-dev/barbacane). Questions about compliance use cases? Reach us at [contact@barbacane.dev](mailto:contact@barbacane.dev).*

0 commit comments

Comments
 (0)