Skip to content

Commit 19ffc8a

Browse files
authored
Update APPROVALS.md
1 parent b152eca commit 19ffc8a

1 file changed

Lines changed: 48 additions & 107 deletions

File tree

docs/APPROVALS.md

Lines changed: 48 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -1,134 +1,75 @@
11
# Approvals (v0)
22

3-
Enterprises do not just want “the policy allowed it.” They want governance evidence:
3+
Enterprises don’t just want “policy allowed it.” They want governance evidence:
4+
- who approved,
5+
- what exactly was approved,
6+
- when it was approved,
7+
- and (optionally) a signature from the approver identity.
48

5-
- who approved
6-
- what exactly was approved
7-
- when it was approved
8-
- whether the approval can be independently verified
9+
IX-Agent-Notary models this as structured objects inside: `policy.approvals[]`.
910

10-
IX-Agent-Notary models that evidence as structured objects inside `policy.approvals[]`.
11+
---
1112

12-
## Approval object
13+
## Approval object (schema-backed)
1314

1415
Each approval is a JSON object with these required fields:
1516

16-
- `approval_id` — unique identifier for the approval record
17-
- `type` — one of:
18-
- `human`
19-
- `ticket`
20-
- `breakglass`
21-
- `status` — one of:
22-
- `requested`
23-
- `approved`
24-
- `denied`
25-
- `expired`
26-
- `revoked`
27-
- `approver` — object with:
28-
- `type`
29-
- `id`
30-
- optional `display`
31-
- `scope` — object with:
32-
- `kind`
33-
- `tool`
34-
- `operation`
35-
- optional `resource`
36-
- `time` — object with:
37-
- `requested_at`
38-
- `decided_at`
39-
- optional `expires_at`
17+
- `approval_id` (string) — unique ID for the approval record
18+
- `type` (enum) — `human | ticket | breakglass`
19+
- `status` (enum) — `requested | approved | denied | expired | revoked`
20+
- `approver` (object)
21+
- `type` (string) — e.g. `user`, `service`, `group`
22+
- `id` (string) — stable identifier (email, IAM principal, etc.)
23+
- `display` (string, optional)
24+
- `scope` (object)
25+
- `kind` (string) — e.g. `tool.invoke`
26+
- `tool` (string)
27+
- `operation` (string)
28+
- `resource` (string, optional) — e.g. path, URL, ARN, ticket ID, etc.
29+
- `time` (object)
30+
- `requested_at` (date-time)
31+
- `decided_at` (date-time)
32+
- `expires_at` (date-time, optional)
4033

4134
Optional fields:
35+
- `notes` (string)
36+
- `signature` (object)
37+
- `alg` (string) — `ed25519`
38+
- `key_id` (string)
39+
- `value` (string) — signature over canonical approval payload (RFC8785), including `signature.alg` and `signature.key_id`, but excluding `signature.value`
4240

43-
- `notes`
44-
- `signature`
41+
---
4542

46-
## Approval signature object
43+
## Approval signatures (implemented)
4744

48-
When present, `signature` must be an object with:
49-
50-
- `alg`
51-
- `key_id`
52-
- `value`
53-
54-
In the current implementation, approval signing uses the same canonicalization rule as receipt signing:
55-
56-
- canonical JSON via **RFC8785-JCS**
57-
- sign the approval payload while excluding `signature.value`
58-
- store the signature as base64url text
59-
60-
## Current implementation behavior
61-
62-
### What the simulator does
63-
64-
The simulator can embed a single approval record when `--approve` is provided.
65-
66-
Example:
67-
68-
```bash
69-
go run ./cmd/ix-an simulate \
70-
--path docs/approved.txt \
71-
--out /tmp/approved.receipt.json \
72-
--approve \
73-
--approver you@example.com \
74-
--approval-type ticket
75-
```
76-
77-
In the current demo flow, the simulator signs the approval object using the same signing key used for the receipt.
78-
79-
### What strict approval verification means
80-
81-
Use `--strict-approvals` when verifying a receipt:
45+
### Simulator emits signed approvals
46+
Run:
8247

8348
```bash
84-
go run ./cmd/ix-an verify \
85-
--strict-hashes \
86-
--strict-signature \
87-
--strict-approvals \
88-
/tmp/approved.receipt.json
89-
```
90-
91-
Under strict approval verification:
92-
93-
- if approvals are present, each approval must include a signature
94-
- each approval signature must verify successfully
95-
- malformed or unsigned approvals cause verification failure
96-
97-
Without `--strict-approvals`, approvals may still be present in the receipt, but the verifier will not require signatures on them.
98-
99-
## Why approvals matter
49+
go run ./cmd/ix-an simulate --path docs/approved.txt --out /tmp/approved.receipt.json \
50+
--approve --approver you@example.com --approval-type ticket
10051

101-
Approvals turn receipts into governance artifacts instead of plain execution logs.
52+
The simulator signs the approval object (demo uses the same key as receipt signing).
10253

103-
That matters for:
54+
Verifier can enforce signed approvals
10455

105-
- SOC 2 and ISO 27001 evidence trails
106-
- change-management linkage
107-
- break-glass event recording
108-
- higher-assurance workflows where risky actions need separate human or ticket authorization
56+
Run:
57+
go run ./cmd/ix-an verify /tmp/approved.receipt.json --strict-approvals --strict-hashes --strict-signature
10958

110-
## Practical interpretation
59+
Strict approvals means:
11160

112-
An approval does **not** replace policy.
113-
It complements policy.
61+
if approvals exist, each approval must include a signature
11462

115-
The pattern is:
63+
each signature must verify
11664

117-
1. policy says whether the action class is even eligible
118-
2. approvals carry governance context for actions that require explicit sign-off
119-
3. the receipt binds policy evidence, approval evidence, and execution evidence into one verifiable record
65+
Why approvals matter (buyer value)
12066

121-
## v0 scope
67+
Approvals turn receipts into auditable governance artifacts:
12268

123-
Current v0 support is intentionally small:
69+
SOC2 / ISO27001 evidence
12470

125-
- one or more structured approval objects in `policy.approvals[]`
126-
- optional approval signatures
127-
- strict verification mode for approval signatures
71+
change-management linkage (ticket approvals)
12872

129-
Future enterprise-grade extensions could add:
73+
break-glass logging (incident-time access)
13074

131-
- quorum approvals
132-
- separate approval trust domains
133-
- external ticket-system binding
134-
- expiry and revocation workflows tied to policy engines
75+
least-privilege + “two-person rule” patterns (future extension)

0 commit comments

Comments
 (0)