@atlasent/safeguard-manifest 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +76 -0
- package/index.d.ts +61 -0
- package/index.js +28 -0
- package/package.json +30 -0
- package/safeguard-manifest.json +527 -0
- package/safeguard-manifest.schema.json +98 -0
package/README.md
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# @atlasent/safeguard-manifest
|
|
2
|
+
|
|
3
|
+
Versioned, deterministic projection of the **authoritative safeguard package**
|
|
4
|
+
(`contract/safeguard-pack/`) into the **design / EXPECTED facts** a consumer needs
|
|
5
|
+
to render the console **SafeguardMap** — per protected action: owner, authority,
|
|
6
|
+
expected evidence sources, and expected gates.
|
|
7
|
+
|
|
8
|
+
## What this is (and is NOT)
|
|
9
|
+
|
|
10
|
+
- **IS:** expected/design truth. What each safeguard is *designed to require*.
|
|
11
|
+
- **IS NOT:** runtime observed state. It carries **no** enforcement mode in
|
|
12
|
+
effect, verification status, coverage, or observed gaps. Those stay live in the
|
|
13
|
+
runtime and are joined by the consumer.
|
|
14
|
+
|
|
15
|
+
The manifest exists so the console never hand-maintains a semantic copy that can
|
|
16
|
+
drift from the Canon / package. This is the single authoritative feed.
|
|
17
|
+
|
|
18
|
+
## The three states it enables
|
|
19
|
+
|
|
20
|
+
The consumer joins this manifest with live runtime facts to produce a
|
|
21
|
+
reconciliation view over three distinct states:
|
|
22
|
+
|
|
23
|
+
| State | Source |
|
|
24
|
+
|---|---|
|
|
25
|
+
| **Expected** | this manifest (versioned safeguard package) |
|
|
26
|
+
| **Configured** | runtime — current configuration (enforcement mode, bound bundle) |
|
|
27
|
+
| **Proven** | runtime — execution + verification evidence (verification_events, coverage) |
|
|
28
|
+
|
|
29
|
+
A safeguard is **not "covered"** merely because it is in the package (Expected) or
|
|
30
|
+
configured in runtime (Configured) — coverage requires observed runtime + acceptance
|
|
31
|
+
evidence (Proven). Where Expected and Configured/Proven disagree, the consumer
|
|
32
|
+
displays the discrepancy as a **gap**; it must not reconcile or reinterpret it.
|
|
33
|
+
|
|
34
|
+
## Regeneration & determinism
|
|
35
|
+
|
|
36
|
+
The JSON is generated by `scripts/generate-safeguard-manifest.py` (in the repo
|
|
37
|
+
root) from the authoritative YAML. It is **deterministic** — same inputs produce
|
|
38
|
+
byte-identical output, so CI fails on any unexpected regeneration diff:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
python3 scripts/generate-safeguard-manifest.py # regenerate
|
|
42
|
+
python3 scripts/generate-safeguard-manifest.py --check # CI: fail if stale
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
**Do not hand-edit `safeguard-manifest.json`.** Change the authoritative
|
|
46
|
+
`contract/safeguard-pack/*` YAML and regenerate.
|
|
47
|
+
|
|
48
|
+
## Provenance
|
|
49
|
+
|
|
50
|
+
- `provenance.source_files[]` records the SHA-256 of each authoritative input —
|
|
51
|
+
identifying the exact inputs deterministically (no volatile git SHA / timestamp
|
|
52
|
+
in the artifact, so `--check` stays stable).
|
|
53
|
+
- Release/commit provenance is bound **at publish time** via npm `--provenance`
|
|
54
|
+
(Sigstore keyless, same trust model as the other AtlaSent published packages).
|
|
55
|
+
|
|
56
|
+
## Distribution & pinning
|
|
57
|
+
|
|
58
|
+
Published through the existing packages release path (`v1_1-release.yml` packs +
|
|
59
|
+
cosign-signs every non-private `packages/*` on a version tag). **Consumers pin an
|
|
60
|
+
explicit `manifest_version` / package version** — never silently consume "latest"
|
|
61
|
+
— and validate the manifest against `safeguard-manifest.schema.json`
|
|
62
|
+
(`schema_version` + provenance) before use.
|
|
63
|
+
|
|
64
|
+
## Usage
|
|
65
|
+
|
|
66
|
+
```ts
|
|
67
|
+
import {
|
|
68
|
+
safeguardManifest,
|
|
69
|
+
getSafeguardAction,
|
|
70
|
+
SAFEGUARD_MANIFEST_VERSION,
|
|
71
|
+
} from "@atlasent/safeguard-manifest";
|
|
72
|
+
|
|
73
|
+
const deploy = getSafeguardAction("production.deploy");
|
|
74
|
+
deploy?.owner_role; // expected owner (design)
|
|
75
|
+
deploy?.expected_evidence_sources; // expected evidence sources (design)
|
|
76
|
+
```
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// Type declarations for @atlasent/safeguard-manifest (zero-build package).
|
|
2
|
+
// The manifest carries DESIGN / EXPECTED facts only — no runtime observed state.
|
|
3
|
+
|
|
4
|
+
export interface SafeguardEvidenceSource {
|
|
5
|
+
capability_id: string;
|
|
6
|
+
tools: string[];
|
|
7
|
+
/** Human safeguard label (only present for actions with a product safeguard-map). */
|
|
8
|
+
safeguard?: string;
|
|
9
|
+
source?: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface SafeguardGateSatisfier {
|
|
13
|
+
capability_id: string;
|
|
14
|
+
via_tools: string[];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface SafeguardExpectedGate {
|
|
18
|
+
gate: string;
|
|
19
|
+
required_assertion_class?: string;
|
|
20
|
+
satisfied_by: SafeguardGateSatisfier[];
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface SafeguardAction {
|
|
24
|
+
id: string;
|
|
25
|
+
business_action: string | null;
|
|
26
|
+
slug: string;
|
|
27
|
+
canon_id: string | null;
|
|
28
|
+
act_id: string | null;
|
|
29
|
+
risk_posture: string | null;
|
|
30
|
+
/** DESIGN facts — the owner/authority the safeguard is designed to require. */
|
|
31
|
+
owner_role: string | null;
|
|
32
|
+
owner_display_name: string | null;
|
|
33
|
+
owner_maps_to_org_role: string | null;
|
|
34
|
+
approver_role: string | null;
|
|
35
|
+
/** Recommended STARTING enforcement mode — a design recommendation, NOT the runtime's observed mode. */
|
|
36
|
+
recommended_lifecycle: string | null;
|
|
37
|
+
expected_gates: SafeguardExpectedGate[];
|
|
38
|
+
expected_evidence_sources: SafeguardEvidenceSource[];
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface SafeguardManifestProvenance {
|
|
42
|
+
source_repo: string;
|
|
43
|
+
source_files: Array<{ path: string; sha256: string }>;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface SafeguardManifest {
|
|
47
|
+
schema_version: string;
|
|
48
|
+
manifest_version: string;
|
|
49
|
+
kind: "safeguard-manifest";
|
|
50
|
+
generated_by?: string;
|
|
51
|
+
notice?: string;
|
|
52
|
+
provenance: SafeguardManifestProvenance;
|
|
53
|
+
actions: SafeguardAction[];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export declare const safeguardManifest: SafeguardManifest;
|
|
57
|
+
export declare const SAFEGUARD_MANIFEST_SCHEMA_VERSION: string;
|
|
58
|
+
export declare const SAFEGUARD_MANIFEST_VERSION: string;
|
|
59
|
+
export declare function getSafeguardAction(idOrSlug: string): SafeguardAction | undefined;
|
|
60
|
+
declare const _default: SafeguardManifest;
|
|
61
|
+
export default _default;
|
package/index.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// @atlasent/safeguard-manifest — zero-build entry.
|
|
2
|
+
//
|
|
3
|
+
// The manifest JSON is GENERATED by scripts/generate-safeguard-manifest.py from
|
|
4
|
+
// contract/safeguard-pack/*. This module is a thin, dependency-free re-export so
|
|
5
|
+
// consumers get typed access (see index.d.ts) without a build step.
|
|
6
|
+
// Do not hand-edit safeguard-manifest.json — regenerate it.
|
|
7
|
+
|
|
8
|
+
"use strict";
|
|
9
|
+
|
|
10
|
+
const manifest = require("./safeguard-manifest.json");
|
|
11
|
+
|
|
12
|
+
/** The generated manifest. All values are design/EXPECTED facts. */
|
|
13
|
+
const safeguardManifest = manifest;
|
|
14
|
+
|
|
15
|
+
/** Look up a protected action's expected/design facts by SG-ACT id or slug. */
|
|
16
|
+
function getSafeguardAction(idOrSlug) {
|
|
17
|
+
return manifest.actions.find(function (a) {
|
|
18
|
+
return a.id === idOrSlug || a.slug === idOrSlug;
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
module.exports = {
|
|
23
|
+
safeguardManifest: safeguardManifest,
|
|
24
|
+
getSafeguardAction: getSafeguardAction,
|
|
25
|
+
SAFEGUARD_MANIFEST_SCHEMA_VERSION: manifest.schema_version,
|
|
26
|
+
SAFEGUARD_MANIFEST_VERSION: manifest.manifest_version,
|
|
27
|
+
default: safeguardManifest,
|
|
28
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@atlasent/safeguard-manifest",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Versioned, deterministic projection of the authoritative AtlaSent safeguard package into the design/EXPECTED facts (owner, authority, expected evidence sources, expected gates) for the console SafeguardMap. Carries no runtime observed state. Zero-build, zero-dependency. Regenerate via scripts/generate-safeguard-manifest.py; do not hand-edit.",
|
|
5
|
+
"main": "./index.js",
|
|
6
|
+
"types": "./index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./index.d.ts",
|
|
10
|
+
"default": "./index.js"
|
|
11
|
+
},
|
|
12
|
+
"./safeguard-manifest.json": "./safeguard-manifest.json",
|
|
13
|
+
"./schema": "./safeguard-manifest.schema.json"
|
|
14
|
+
},
|
|
15
|
+
"scripts": {
|
|
16
|
+
"generate": "python3 ../../scripts/generate-safeguard-manifest.py",
|
|
17
|
+
"check": "python3 ../../scripts/generate-safeguard-manifest.py --check"
|
|
18
|
+
},
|
|
19
|
+
"files": [
|
|
20
|
+
"index.js",
|
|
21
|
+
"index.d.ts",
|
|
22
|
+
"safeguard-manifest.json",
|
|
23
|
+
"safeguard-manifest.schema.json"
|
|
24
|
+
],
|
|
25
|
+
"publishConfig": {
|
|
26
|
+
"access": "public",
|
|
27
|
+
"provenance": true
|
|
28
|
+
},
|
|
29
|
+
"license": "MIT"
|
|
30
|
+
}
|
|
@@ -0,0 +1,527 @@
|
|
|
1
|
+
{
|
|
2
|
+
"actions": [
|
|
3
|
+
{
|
|
4
|
+
"act_id": "ACT-0001",
|
|
5
|
+
"approver_role": "approver",
|
|
6
|
+
"business_action": "Production deployment",
|
|
7
|
+
"canon_id": "CANON-000001",
|
|
8
|
+
"expected_evidence_sources": [
|
|
9
|
+
{
|
|
10
|
+
"capability_id": "change_review.approved",
|
|
11
|
+
"safeguard": "Review",
|
|
12
|
+
"source": "GitHub",
|
|
13
|
+
"tools": [
|
|
14
|
+
"github"
|
|
15
|
+
]
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"capability_id": "change_request.approved",
|
|
19
|
+
"tools": [
|
|
20
|
+
"jira",
|
|
21
|
+
"servicenow"
|
|
22
|
+
]
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"capability_id": "state.snapshot_captured",
|
|
26
|
+
"safeguard": "Artifact identity",
|
|
27
|
+
"source": "build or registry",
|
|
28
|
+
"tools": [
|
|
29
|
+
"github-actions",
|
|
30
|
+
"terraform"
|
|
31
|
+
]
|
|
32
|
+
}
|
|
33
|
+
],
|
|
34
|
+
"expected_gates": [
|
|
35
|
+
{
|
|
36
|
+
"gate": "requires_human_approval",
|
|
37
|
+
"satisfied_by": [
|
|
38
|
+
{
|
|
39
|
+
"capability_id": "change_review.approved",
|
|
40
|
+
"via_tools": [
|
|
41
|
+
"github"
|
|
42
|
+
]
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"capability_id": "change_request.approved",
|
|
46
|
+
"via_tools": [
|
|
47
|
+
"jira",
|
|
48
|
+
"servicenow"
|
|
49
|
+
]
|
|
50
|
+
}
|
|
51
|
+
]
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"gate": "requires_state_snapshot",
|
|
55
|
+
"satisfied_by": [
|
|
56
|
+
{
|
|
57
|
+
"capability_id": "state.snapshot_captured",
|
|
58
|
+
"via_tools": [
|
|
59
|
+
"github-actions",
|
|
60
|
+
"terraform"
|
|
61
|
+
]
|
|
62
|
+
}
|
|
63
|
+
]
|
|
64
|
+
}
|
|
65
|
+
],
|
|
66
|
+
"id": "SG-ACT-001",
|
|
67
|
+
"owner_display_name": "Release Owner",
|
|
68
|
+
"owner_maps_to_org_role": "admin",
|
|
69
|
+
"owner_role": "release_owner",
|
|
70
|
+
"recommended_lifecycle": "shadow",
|
|
71
|
+
"risk_posture": "high",
|
|
72
|
+
"slug": "production.deploy"
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"act_id": "ACT-0036",
|
|
76
|
+
"approver_role": "approver",
|
|
77
|
+
"business_action": "Infrastructure change",
|
|
78
|
+
"canon_id": "CANON-000033",
|
|
79
|
+
"expected_evidence_sources": [
|
|
80
|
+
{
|
|
81
|
+
"capability_id": "change_request.approved",
|
|
82
|
+
"tools": [
|
|
83
|
+
"jira",
|
|
84
|
+
"servicenow"
|
|
85
|
+
]
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
"capability_id": "change_review.approved",
|
|
89
|
+
"tools": [
|
|
90
|
+
"github"
|
|
91
|
+
]
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
"capability_id": "state.snapshot_captured",
|
|
95
|
+
"tools": [
|
|
96
|
+
"github-actions",
|
|
97
|
+
"terraform"
|
|
98
|
+
]
|
|
99
|
+
}
|
|
100
|
+
],
|
|
101
|
+
"expected_gates": [
|
|
102
|
+
{
|
|
103
|
+
"gate": "requires_human_approval",
|
|
104
|
+
"satisfied_by": [
|
|
105
|
+
{
|
|
106
|
+
"capability_id": "change_request.approved",
|
|
107
|
+
"via_tools": [
|
|
108
|
+
"jira",
|
|
109
|
+
"servicenow"
|
|
110
|
+
]
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
"capability_id": "change_review.approved",
|
|
114
|
+
"via_tools": [
|
|
115
|
+
"github"
|
|
116
|
+
]
|
|
117
|
+
}
|
|
118
|
+
]
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
"gate": "requires_state_snapshot",
|
|
122
|
+
"satisfied_by": [
|
|
123
|
+
{
|
|
124
|
+
"capability_id": "state.snapshot_captured",
|
|
125
|
+
"via_tools": [
|
|
126
|
+
"github-actions",
|
|
127
|
+
"terraform"
|
|
128
|
+
]
|
|
129
|
+
}
|
|
130
|
+
]
|
|
131
|
+
}
|
|
132
|
+
],
|
|
133
|
+
"id": "SG-ACT-002",
|
|
134
|
+
"owner_display_name": "Infrastructure Owner",
|
|
135
|
+
"owner_maps_to_org_role": "admin",
|
|
136
|
+
"owner_role": "infra_owner",
|
|
137
|
+
"recommended_lifecycle": "shadow",
|
|
138
|
+
"risk_posture": "high",
|
|
139
|
+
"slug": "infrastructure.change"
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
"act_id": "ACT-0035",
|
|
143
|
+
"approver_role": "approver",
|
|
144
|
+
"business_action": "Database migration",
|
|
145
|
+
"canon_id": "CANON-000032",
|
|
146
|
+
"expected_evidence_sources": [
|
|
147
|
+
{
|
|
148
|
+
"capability_id": "change_review.approved",
|
|
149
|
+
"tools": [
|
|
150
|
+
"github"
|
|
151
|
+
]
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
"capability_id": "change_request.approved",
|
|
155
|
+
"tools": [
|
|
156
|
+
"jira",
|
|
157
|
+
"servicenow"
|
|
158
|
+
]
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
"capability_id": "state.snapshot_captured",
|
|
162
|
+
"tools": [
|
|
163
|
+
"github-actions",
|
|
164
|
+
"terraform"
|
|
165
|
+
]
|
|
166
|
+
}
|
|
167
|
+
],
|
|
168
|
+
"expected_gates": [
|
|
169
|
+
{
|
|
170
|
+
"gate": "requires_human_approval",
|
|
171
|
+
"satisfied_by": [
|
|
172
|
+
{
|
|
173
|
+
"capability_id": "change_review.approved",
|
|
174
|
+
"via_tools": [
|
|
175
|
+
"github"
|
|
176
|
+
]
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
"capability_id": "change_request.approved",
|
|
180
|
+
"via_tools": [
|
|
181
|
+
"jira",
|
|
182
|
+
"servicenow"
|
|
183
|
+
]
|
|
184
|
+
}
|
|
185
|
+
]
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
"gate": "requires_state_snapshot",
|
|
189
|
+
"satisfied_by": [
|
|
190
|
+
{
|
|
191
|
+
"capability_id": "state.snapshot_captured",
|
|
192
|
+
"via_tools": [
|
|
193
|
+
"github-actions",
|
|
194
|
+
"terraform"
|
|
195
|
+
]
|
|
196
|
+
}
|
|
197
|
+
]
|
|
198
|
+
}
|
|
199
|
+
],
|
|
200
|
+
"id": "SG-ACT-003",
|
|
201
|
+
"owner_display_name": "Database Owner",
|
|
202
|
+
"owner_maps_to_org_role": "admin",
|
|
203
|
+
"owner_role": "dba_owner",
|
|
204
|
+
"recommended_lifecycle": "shadow",
|
|
205
|
+
"risk_posture": "high",
|
|
206
|
+
"slug": "database.migrate"
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
"act_id": "ACT-0032",
|
|
210
|
+
"approver_role": "approver",
|
|
211
|
+
"business_action": "Security-control exception",
|
|
212
|
+
"canon_id": "CANON-000029",
|
|
213
|
+
"expected_evidence_sources": [
|
|
214
|
+
{
|
|
215
|
+
"capability_id": "change_request.approved",
|
|
216
|
+
"tools": [
|
|
217
|
+
"jira",
|
|
218
|
+
"servicenow"
|
|
219
|
+
]
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
"capability_id": "caller.mfa_satisfied",
|
|
223
|
+
"tools": [
|
|
224
|
+
"entra-id",
|
|
225
|
+
"okta"
|
|
226
|
+
]
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
"capability_id": "caller.identity_verified",
|
|
230
|
+
"tools": [
|
|
231
|
+
"entra-id",
|
|
232
|
+
"okta"
|
|
233
|
+
]
|
|
234
|
+
},
|
|
235
|
+
{
|
|
236
|
+
"capability_id": "state.snapshot_captured",
|
|
237
|
+
"tools": [
|
|
238
|
+
"generic-webhook",
|
|
239
|
+
"terraform"
|
|
240
|
+
]
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
"capability_id": "caller.role_membership_asserted",
|
|
244
|
+
"tools": [
|
|
245
|
+
"entra-id",
|
|
246
|
+
"okta"
|
|
247
|
+
]
|
|
248
|
+
},
|
|
249
|
+
{
|
|
250
|
+
"capability_id": "risk.assessment_recorded",
|
|
251
|
+
"tools": [
|
|
252
|
+
"generic-webhook",
|
|
253
|
+
"servicenow"
|
|
254
|
+
]
|
|
255
|
+
}
|
|
256
|
+
],
|
|
257
|
+
"expected_gates": [
|
|
258
|
+
{
|
|
259
|
+
"gate": "requires_human_approval",
|
|
260
|
+
"satisfied_by": [
|
|
261
|
+
{
|
|
262
|
+
"capability_id": "change_request.approved",
|
|
263
|
+
"via_tools": [
|
|
264
|
+
"jira",
|
|
265
|
+
"servicenow"
|
|
266
|
+
]
|
|
267
|
+
}
|
|
268
|
+
]
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
"gate": "requires_mfa",
|
|
272
|
+
"satisfied_by": [
|
|
273
|
+
{
|
|
274
|
+
"capability_id": "caller.mfa_satisfied",
|
|
275
|
+
"via_tools": [
|
|
276
|
+
"entra-id",
|
|
277
|
+
"okta"
|
|
278
|
+
]
|
|
279
|
+
}
|
|
280
|
+
]
|
|
281
|
+
},
|
|
282
|
+
{
|
|
283
|
+
"gate": "requires_verified_actor",
|
|
284
|
+
"satisfied_by": [
|
|
285
|
+
{
|
|
286
|
+
"capability_id": "caller.identity_verified",
|
|
287
|
+
"via_tools": [
|
|
288
|
+
"entra-id",
|
|
289
|
+
"okta"
|
|
290
|
+
]
|
|
291
|
+
}
|
|
292
|
+
]
|
|
293
|
+
},
|
|
294
|
+
{
|
|
295
|
+
"gate": "requires_state_snapshot",
|
|
296
|
+
"satisfied_by": [
|
|
297
|
+
{
|
|
298
|
+
"capability_id": "state.snapshot_captured",
|
|
299
|
+
"via_tools": [
|
|
300
|
+
"generic-webhook",
|
|
301
|
+
"terraform"
|
|
302
|
+
]
|
|
303
|
+
}
|
|
304
|
+
]
|
|
305
|
+
},
|
|
306
|
+
{
|
|
307
|
+
"gate": "required_assertion_classes",
|
|
308
|
+
"required_assertion_class": "identity",
|
|
309
|
+
"satisfied_by": [
|
|
310
|
+
{
|
|
311
|
+
"capability_id": "caller.identity_verified",
|
|
312
|
+
"via_tools": [
|
|
313
|
+
"entra-id",
|
|
314
|
+
"okta"
|
|
315
|
+
]
|
|
316
|
+
},
|
|
317
|
+
{
|
|
318
|
+
"capability_id": "caller.role_membership_asserted",
|
|
319
|
+
"via_tools": [
|
|
320
|
+
"entra-id",
|
|
321
|
+
"okta"
|
|
322
|
+
]
|
|
323
|
+
}
|
|
324
|
+
]
|
|
325
|
+
},
|
|
326
|
+
{
|
|
327
|
+
"gate": "required_assertion_classes",
|
|
328
|
+
"required_assertion_class": "risk",
|
|
329
|
+
"satisfied_by": [
|
|
330
|
+
{
|
|
331
|
+
"capability_id": "risk.assessment_recorded",
|
|
332
|
+
"via_tools": [
|
|
333
|
+
"generic-webhook",
|
|
334
|
+
"servicenow"
|
|
335
|
+
]
|
|
336
|
+
}
|
|
337
|
+
]
|
|
338
|
+
}
|
|
339
|
+
],
|
|
340
|
+
"id": "SG-ACT-004",
|
|
341
|
+
"owner_display_name": "Security Owner",
|
|
342
|
+
"owner_maps_to_org_role": "owner",
|
|
343
|
+
"owner_role": "security_owner",
|
|
344
|
+
"recommended_lifecycle": "shadow",
|
|
345
|
+
"risk_posture": "critical",
|
|
346
|
+
"slug": "security.breakglass"
|
|
347
|
+
},
|
|
348
|
+
{
|
|
349
|
+
"act_id": "ACT-0031",
|
|
350
|
+
"approver_role": "approver",
|
|
351
|
+
"business_action": "Customer-production-data access",
|
|
352
|
+
"canon_id": "CANON-000028",
|
|
353
|
+
"expected_evidence_sources": [
|
|
354
|
+
{
|
|
355
|
+
"capability_id": "change_request.approved",
|
|
356
|
+
"tools": [
|
|
357
|
+
"jira",
|
|
358
|
+
"servicenow"
|
|
359
|
+
]
|
|
360
|
+
},
|
|
361
|
+
{
|
|
362
|
+
"capability_id": "change_review.approved",
|
|
363
|
+
"tools": [
|
|
364
|
+
"github"
|
|
365
|
+
]
|
|
366
|
+
},
|
|
367
|
+
{
|
|
368
|
+
"capability_id": "consent.obtained",
|
|
369
|
+
"tools": [
|
|
370
|
+
"generic-webhook"
|
|
371
|
+
]
|
|
372
|
+
},
|
|
373
|
+
{
|
|
374
|
+
"capability_id": "data.residency_asserted",
|
|
375
|
+
"tools": [
|
|
376
|
+
"aws",
|
|
377
|
+
"generic-webhook"
|
|
378
|
+
]
|
|
379
|
+
}
|
|
380
|
+
],
|
|
381
|
+
"expected_gates": [
|
|
382
|
+
{
|
|
383
|
+
"gate": "requires_human_approval",
|
|
384
|
+
"satisfied_by": [
|
|
385
|
+
{
|
|
386
|
+
"capability_id": "change_request.approved",
|
|
387
|
+
"via_tools": [
|
|
388
|
+
"jira",
|
|
389
|
+
"servicenow"
|
|
390
|
+
]
|
|
391
|
+
},
|
|
392
|
+
{
|
|
393
|
+
"capability_id": "change_review.approved",
|
|
394
|
+
"via_tools": [
|
|
395
|
+
"github"
|
|
396
|
+
]
|
|
397
|
+
}
|
|
398
|
+
]
|
|
399
|
+
},
|
|
400
|
+
{
|
|
401
|
+
"gate": "required_assertion_classes",
|
|
402
|
+
"required_assertion_class": "consent",
|
|
403
|
+
"satisfied_by": [
|
|
404
|
+
{
|
|
405
|
+
"capability_id": "consent.obtained",
|
|
406
|
+
"via_tools": [
|
|
407
|
+
"generic-webhook"
|
|
408
|
+
]
|
|
409
|
+
}
|
|
410
|
+
]
|
|
411
|
+
},
|
|
412
|
+
{
|
|
413
|
+
"gate": "required_assertion_classes",
|
|
414
|
+
"required_assertion_class": "residency",
|
|
415
|
+
"satisfied_by": [
|
|
416
|
+
{
|
|
417
|
+
"capability_id": "data.residency_asserted",
|
|
418
|
+
"via_tools": [
|
|
419
|
+
"aws",
|
|
420
|
+
"generic-webhook"
|
|
421
|
+
]
|
|
422
|
+
}
|
|
423
|
+
]
|
|
424
|
+
}
|
|
425
|
+
],
|
|
426
|
+
"id": "SG-ACT-005",
|
|
427
|
+
"owner_display_name": "Data Owner",
|
|
428
|
+
"owner_maps_to_org_role": "admin",
|
|
429
|
+
"owner_role": "data_owner",
|
|
430
|
+
"recommended_lifecycle": "shadow",
|
|
431
|
+
"risk_posture": "high",
|
|
432
|
+
"slug": "data.export"
|
|
433
|
+
},
|
|
434
|
+
{
|
|
435
|
+
"act_id": "ACT-0029",
|
|
436
|
+
"approver_role": "approver",
|
|
437
|
+
"business_action": "AI-agent production action",
|
|
438
|
+
"canon_id": "CANON-000026",
|
|
439
|
+
"expected_evidence_sources": [
|
|
440
|
+
{
|
|
441
|
+
"capability_id": "caller.identity_verified",
|
|
442
|
+
"tools": [
|
|
443
|
+
"generic-webhook",
|
|
444
|
+
"github-actions",
|
|
445
|
+
"okta"
|
|
446
|
+
]
|
|
447
|
+
},
|
|
448
|
+
{
|
|
449
|
+
"capability_id": "risk.assessment_recorded",
|
|
450
|
+
"tools": [
|
|
451
|
+
"generic-webhook"
|
|
452
|
+
]
|
|
453
|
+
}
|
|
454
|
+
],
|
|
455
|
+
"expected_gates": [
|
|
456
|
+
{
|
|
457
|
+
"gate": "requires_verified_actor",
|
|
458
|
+
"satisfied_by": [
|
|
459
|
+
{
|
|
460
|
+
"capability_id": "caller.identity_verified",
|
|
461
|
+
"via_tools": [
|
|
462
|
+
"generic-webhook",
|
|
463
|
+
"github-actions",
|
|
464
|
+
"okta"
|
|
465
|
+
]
|
|
466
|
+
}
|
|
467
|
+
]
|
|
468
|
+
},
|
|
469
|
+
{
|
|
470
|
+
"gate": "required_assertion_classes",
|
|
471
|
+
"required_assertion_class": "identity",
|
|
472
|
+
"satisfied_by": [
|
|
473
|
+
{
|
|
474
|
+
"capability_id": "caller.identity_verified",
|
|
475
|
+
"via_tools": [
|
|
476
|
+
"generic-webhook",
|
|
477
|
+
"github-actions",
|
|
478
|
+
"okta"
|
|
479
|
+
]
|
|
480
|
+
}
|
|
481
|
+
]
|
|
482
|
+
},
|
|
483
|
+
{
|
|
484
|
+
"gate": "required_assertion_classes",
|
|
485
|
+
"required_assertion_class": "risk",
|
|
486
|
+
"satisfied_by": [
|
|
487
|
+
{
|
|
488
|
+
"capability_id": "risk.assessment_recorded",
|
|
489
|
+
"via_tools": [
|
|
490
|
+
"generic-webhook"
|
|
491
|
+
]
|
|
492
|
+
}
|
|
493
|
+
]
|
|
494
|
+
}
|
|
495
|
+
],
|
|
496
|
+
"id": "SG-ACT-006",
|
|
497
|
+
"owner_display_name": "Agent Owner",
|
|
498
|
+
"owner_maps_to_org_role": "admin",
|
|
499
|
+
"owner_role": "agent_owner",
|
|
500
|
+
"recommended_lifecycle": "shadow",
|
|
501
|
+
"risk_posture": "high",
|
|
502
|
+
"slug": "agent.tool.invoke"
|
|
503
|
+
}
|
|
504
|
+
],
|
|
505
|
+
"generated_by": "scripts/generate-safeguard-manifest.py",
|
|
506
|
+
"kind": "safeguard-manifest",
|
|
507
|
+
"manifest_version": "1.0.0",
|
|
508
|
+
"notice": "DESIGN/EXPECTED facts only \u2014 no runtime observed state. Deterministic; do not hand-edit.",
|
|
509
|
+
"provenance": {
|
|
510
|
+
"source_files": [
|
|
511
|
+
{
|
|
512
|
+
"path": "contract/safeguard-pack/authority/authority-model.yaml",
|
|
513
|
+
"sha256": "6a303d2ce35ddd4ff7c2539b8ab2ee69411af2d65ab52ebcf0e5f12020fe9c47"
|
|
514
|
+
},
|
|
515
|
+
{
|
|
516
|
+
"path": "contract/safeguard-pack/products/saas-production-safeguard/safeguard-map.yaml",
|
|
517
|
+
"sha256": "e14a8ee6ce3b6a7a2171c0ac3de70a2f713d46f1c808131b5aee9ee241fb68b4"
|
|
518
|
+
},
|
|
519
|
+
{
|
|
520
|
+
"path": "contract/safeguard-pack/protected-actions/safeguard-actions.yaml",
|
|
521
|
+
"sha256": "6932a4c9c7aac3e9e7a17480ca9921ecf1f1942115778963f82488bb2738de68"
|
|
522
|
+
}
|
|
523
|
+
],
|
|
524
|
+
"source_repo": "AtlaSent-Systems-Inc/atlasent"
|
|
525
|
+
},
|
|
526
|
+
"schema_version": "1.0"
|
|
527
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"$id": "https://atlasent.io/schemas/safeguard-manifest.schema.json",
|
|
4
|
+
"title": "Safeguard Manifest",
|
|
5
|
+
"description": "Versioned, deterministic projection of the authoritative safeguard package (safeguard-actions + authority-model + safeguard-map) into the design/EXPECTED facts a consumer needs: per protected action, its owner, authority, expected evidence sources, and expected gates. Carries NO runtime observed state (enforcement mode in effect, verification status, coverage, gaps) — those stay live in the runtime. Consumers pin an explicit manifest_version and must validate provenance.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"required": ["schema_version", "manifest_version", "kind", "provenance", "actions"],
|
|
9
|
+
"properties": {
|
|
10
|
+
"schema_version": { "type": "string", "const": "1.0" },
|
|
11
|
+
"manifest_version": { "type": "string", "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$" },
|
|
12
|
+
"kind": { "type": "string", "const": "safeguard-manifest" },
|
|
13
|
+
"generated_by": { "type": "string" },
|
|
14
|
+
"notice": { "type": "string" },
|
|
15
|
+
"provenance": {
|
|
16
|
+
"type": "object",
|
|
17
|
+
"additionalProperties": false,
|
|
18
|
+
"required": ["source_repo", "source_files"],
|
|
19
|
+
"description": "Deterministic input provenance. Release/commit provenance is bound at publish time (npm --provenance / Sigstore), not baked here.",
|
|
20
|
+
"properties": {
|
|
21
|
+
"source_repo": { "type": "string" },
|
|
22
|
+
"source_files": {
|
|
23
|
+
"type": "array",
|
|
24
|
+
"minItems": 1,
|
|
25
|
+
"items": {
|
|
26
|
+
"type": "object",
|
|
27
|
+
"additionalProperties": false,
|
|
28
|
+
"required": ["path", "sha256"],
|
|
29
|
+
"properties": {
|
|
30
|
+
"path": { "type": "string" },
|
|
31
|
+
"sha256": { "type": "string", "pattern": "^[0-9a-f]{64}$" }
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
"actions": {
|
|
38
|
+
"type": "array",
|
|
39
|
+
"minItems": 1,
|
|
40
|
+
"items": {
|
|
41
|
+
"type": "object",
|
|
42
|
+
"additionalProperties": false,
|
|
43
|
+
"required": ["id", "slug", "owner_role", "expected_gates", "expected_evidence_sources"],
|
|
44
|
+
"properties": {
|
|
45
|
+
"id": { "type": "string", "pattern": "^SG-ACT-[0-9]{3}$" },
|
|
46
|
+
"business_action": { "type": ["string", "null"] },
|
|
47
|
+
"slug": { "type": "string" },
|
|
48
|
+
"canon_id": { "type": ["string", "null"] },
|
|
49
|
+
"act_id": { "type": ["string", "null"] },
|
|
50
|
+
"risk_posture": { "type": ["string", "null"] },
|
|
51
|
+
"owner_role": { "type": ["string", "null"] },
|
|
52
|
+
"owner_display_name": { "type": ["string", "null"] },
|
|
53
|
+
"owner_maps_to_org_role": { "type": ["string", "null"] },
|
|
54
|
+
"approver_role": { "type": ["string", "null"] },
|
|
55
|
+
"recommended_lifecycle": { "type": ["string", "null"] },
|
|
56
|
+
"expected_gates": {
|
|
57
|
+
"type": "array",
|
|
58
|
+
"items": {
|
|
59
|
+
"type": "object",
|
|
60
|
+
"additionalProperties": false,
|
|
61
|
+
"required": ["gate", "satisfied_by"],
|
|
62
|
+
"properties": {
|
|
63
|
+
"gate": { "type": "string" },
|
|
64
|
+
"required_assertion_class": { "type": "string" },
|
|
65
|
+
"satisfied_by": {
|
|
66
|
+
"type": "array",
|
|
67
|
+
"items": {
|
|
68
|
+
"type": "object",
|
|
69
|
+
"additionalProperties": false,
|
|
70
|
+
"required": ["capability_id", "via_tools"],
|
|
71
|
+
"properties": {
|
|
72
|
+
"capability_id": { "type": "string" },
|
|
73
|
+
"via_tools": { "type": "array", "items": { "type": "string" } }
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
"expected_evidence_sources": {
|
|
81
|
+
"type": "array",
|
|
82
|
+
"items": {
|
|
83
|
+
"type": "object",
|
|
84
|
+
"additionalProperties": false,
|
|
85
|
+
"required": ["capability_id", "tools"],
|
|
86
|
+
"properties": {
|
|
87
|
+
"capability_id": { "type": "string" },
|
|
88
|
+
"tools": { "type": "array", "items": { "type": "string" } },
|
|
89
|
+
"safeguard": { "type": "string" },
|
|
90
|
+
"source": { "type": "string" }
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|