@agent-ix/spec-objects-security 0.4.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/LICENSE +661 -0
- package/README.md +109 -0
- package/manifest.yaml +464 -0
- package/package.json +33 -0
- package/skeletons/asset.md +22 -0
- package/skeletons/attack_surface.md +25 -0
- package/skeletons/audit_event.md +34 -0
- package/skeletons/audit_finding.md +25 -0
- package/skeletons/auth_flow.md +31 -0
- package/skeletons/control.md +24 -0
- package/skeletons/cors_policy.md +24 -0
- package/skeletons/csrf_token.md +19 -0
- package/skeletons/data_classification.md +25 -0
- package/skeletons/encryption_key.md +18 -0
- package/skeletons/jwt_claim.md +27 -0
- package/skeletons/mfa_method.md +19 -0
- package/skeletons/password_policy.md +26 -0
- package/skeletons/permission.md +18 -0
- package/skeletons/policy.md +25 -0
- package/skeletons/risk.md +20 -0
- package/skeletons/role.md +21 -0
- package/skeletons/scope.md +20 -0
- package/skeletons/secret.md +25 -0
- package/skeletons/session_config.md +24 -0
- package/skeletons/threat.md +19 -0
- package/skeletons/trust_boundary.md +26 -0
- package/skeletons/vulnerability.md +21 -0
package/README.md
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# spec-objects-security
|
|
2
|
+
|
|
3
|
+
> Filament Module: tier-2 security and identity ObjectTypes (threats, controls, auth flows, secrets, policies)
|
|
4
|
+
|
|
5
|
+
`spec-objects-security` is an **Agent-IX Filament module**: a `manifest.yaml` plus per-kind authoring **skeletons** (and frontmatter schemas) that teach the spec tooling a vocabulary of object kinds. It is not a standalone app — it is loaded by [`quire-cli`](https://github.com/agent-ix/quire-cli) and [`quoin`](https://github.com/agent-ix/quoin) to author and validate Markdown spec artifacts.
|
|
6
|
+
|
|
7
|
+
## Installing quire-cli
|
|
8
|
+
|
|
9
|
+
`@agent-ix` packages are published to public npm. Install the CLI globally:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install -g @agent-ix/quire-cli
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
See https://github.com/agent-ix/quire-cli#install for details.
|
|
16
|
+
|
|
17
|
+
## Install this module via npm
|
|
18
|
+
|
|
19
|
+
This module is also published as a config-only npm package: `@agent-ix/spec-objects-security`.
|
|
20
|
+
The package root **is** the Filament module (`manifest.yaml` + schemas/skeletons),
|
|
21
|
+
so it works directly as a `--module` target or via quoin's `package:` source.
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install @agent-ix/spec-objects-security
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
# quoin — resolve the module from npm by name
|
|
29
|
+
quoin plugin install package:@agent-ix/spec-objects-security
|
|
30
|
+
|
|
31
|
+
# or point any tool at the installed package root
|
|
32
|
+
quire validate spec/**/*.md --module node_modules/@agent-ix/spec-objects-security
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Object types provided
|
|
36
|
+
|
|
37
|
+
This module adds the following object kinds (frontmatter `type:` value in parentheses). All kinds are tier-2 embedded ObjectTypes — they require `id`, `title` and `type` in frontmatter plus the kind-specific contract below.
|
|
38
|
+
|
|
39
|
+
| Object | `type:` | Description |
|
|
40
|
+
|--------|---------|-------------|
|
|
41
|
+
| Auth flow | `auth_flow` | An authentication/login flow, with a `Flow` section carrying a mermaid diagram of the sequence (e.g. OIDC authorization code flow). |
|
|
42
|
+
| Permission | `permission` | A single grantable permission, naming the protected `resource` kind and the `verb` (action) it grants on it. |
|
|
43
|
+
| Scope | `scope` | An OAuth/authorization scope, with a `Grants` section listing the permissions the scope confers. |
|
|
44
|
+
| Role | `role` | A named role, with a `Permissions` section listing the permissions bound to it. |
|
|
45
|
+
| Secret | `secret` | A managed secret (e.g. client secret), with a `Rotation` section describing how and how often it rotates. |
|
|
46
|
+
| Encryption key | `encryption_key` | An encryption key, with frontmatter `algorithm` (cipher) and optional `rotation` cadence. |
|
|
47
|
+
| Session config | `session_config` | A session configuration, with a `Settings` section enumerating the effective session parameters (cookies, timeouts, limits). |
|
|
48
|
+
| Data classification | `data_classification` | A data sensitivity class, with a `Handling` section stating the handling requirements for that class. |
|
|
49
|
+
| Trust boundary | `trust_boundary` | A trust boundary between security zones, with a `Boundary` section carrying a mermaid diagram of the zones. |
|
|
50
|
+
| Audit event | `audit_event` | An emitted audit/log event, with an `Event Schema` section carrying a JSON code block of its payload schema. |
|
|
51
|
+
| CSRF token | `csrf_token` | A CSRF-protection token, with frontmatter `rotation_window` (how often a fresh token is issued). |
|
|
52
|
+
| CORS policy | `cors_policy` | A browser cross-origin policy, with an `Origins` section enumerating the allowed origins and their rules. |
|
|
53
|
+
| Password policy | `password_policy` | A password policy, with a `Rules` section enumerating the enforced password rules. |
|
|
54
|
+
| MFA method | `mfa_method` | A multi-factor authentication method, with frontmatter `kind` (method kind) and optional `factor` (auth factor class). |
|
|
55
|
+
| JWT claim | `jwt_claim` | A JWT/token claim, with a `Schema` section carrying a JSON code block of the claim's JSON Schema. |
|
|
56
|
+
| Threat | `threat` | A threat, with frontmatter `stride_category` (STRIDE class) and `vector` (the attack vector). |
|
|
57
|
+
| Control | `control` | A security control, with a `Mappings` section mapping it to the threats, risks and standards it addresses. |
|
|
58
|
+
| Risk | `risk` | A risk-register entry, with frontmatter `likelihood` and `impact` qualitative ratings driving its score. |
|
|
59
|
+
| Vulnerability | `vulnerability` | A vulnerability, with frontmatter `severity` and optional `cve_id` linking the public advisory. |
|
|
60
|
+
| Asset | `asset` | A protected asset, with a `Description` section describing the asset and why it matters. |
|
|
61
|
+
| Attack surface | `attack_surface` | An attack surface, with an `Entry Points` section enumerating the externally reachable entry points. |
|
|
62
|
+
| Policy | `policy` | A normative security policy, with a `Policy` section stating the policy text. |
|
|
63
|
+
| Audit finding | `audit_finding` | A security-audit finding, with a `Recommendation` section stating the remediation recommendation. |
|
|
64
|
+
|
|
65
|
+
## How this module is used
|
|
66
|
+
|
|
67
|
+
### With quoin (recommended)
|
|
68
|
+
|
|
69
|
+
[`quoin`](https://github.com/agent-ix/quoin) is the spec-domain authoring CLI. Install the module as a plugin, then author and validate:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
quoin plugin install path:../spec-objects-security
|
|
73
|
+
quoin catalog list # list the kinds this module adds
|
|
74
|
+
quoin write . --types threat,control # scaffold artifacts of these kinds
|
|
75
|
+
quoin review # validate authored files
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### With quire-cli directly
|
|
79
|
+
|
|
80
|
+
Point `quire` at this module (the package directory holds `manifest.yaml` and `skeletons/`):
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
quire schema threat --module ./spec_objects_security # a kind's extraction contract
|
|
84
|
+
quire validate spec/**/*.md --module ./spec_objects_security # structural validation
|
|
85
|
+
quire extract <DOC> --module ./spec_objects_security # extract structured data
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
See the [quire-cli usage docs](https://github.com/agent-ix/quire-cli#usage-instructions) for all commands.
|
|
89
|
+
|
|
90
|
+
## Development
|
|
91
|
+
|
|
92
|
+
This module is a flat-layout Python package (`spec_objects_security`, Python 3.13+) managed with [Poetry](https://python-poetry.org/) and built/published via GitHub Actions to Google Artifact Registry (PyPI-compatible).
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
make install # install dependencies in the Poetry venv
|
|
96
|
+
make test # run pytest
|
|
97
|
+
make lint # ruff + black --check
|
|
98
|
+
make format # auto-format (ruff --fix + black)
|
|
99
|
+
make build # build wheel + sdist under dist/
|
|
100
|
+
make local-publish # publish to the local pypi.ix registry
|
|
101
|
+
make update-lock # update poetry.lock
|
|
102
|
+
make use-local p=<name> / make use-upstream p=<name> # swap a dep source
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
**CI:** GitHub Actions runs on `push`, `pull_request`, and `v*.*.*` tags — it tests, lints, builds with `poetry build`, and on tags publishes via `twine upload -r internal-pypi`. Versioning is dynamic from the Git tag. Required CI config: `GCP_SERVICE_ACCOUNT_KEY` (secret) plus `GCP_REGION`, `GCP_PROJECT_NAME`, `GCP_PYPI` (variables).
|
|
106
|
+
|
|
107
|
+
## License
|
|
108
|
+
|
|
109
|
+
AGPL-3.0-or-later — see [LICENSE](./LICENSE).
|
package/manifest.yaml
ADDED
|
@@ -0,0 +1,464 @@
|
|
|
1
|
+
manifest_version: 1.0.0
|
|
2
|
+
name: spec-objects-security
|
|
3
|
+
version: 0.1.0
|
|
4
|
+
description: 'Filament Module: tier-2 security and identity ObjectTypes (threats, controls, auth flows, secrets, policies)'
|
|
5
|
+
nav:
|
|
6
|
+
category:
|
|
7
|
+
slug: security
|
|
8
|
+
label: Security
|
|
9
|
+
icon: ShieldCheck
|
|
10
|
+
order: 54
|
|
11
|
+
archetypes: []
|
|
12
|
+
grammars: []
|
|
13
|
+
artifact_types: []
|
|
14
|
+
lint_rules: []
|
|
15
|
+
object_types:
|
|
16
|
+
- name: auth_flow
|
|
17
|
+
roles: [externally-exposed]
|
|
18
|
+
allowed_links:
|
|
19
|
+
requires: [mfa_method]
|
|
20
|
+
grants: [role]
|
|
21
|
+
protects: [externally-exposed]
|
|
22
|
+
references: [auth_flow]
|
|
23
|
+
data_schema:
|
|
24
|
+
type: object
|
|
25
|
+
body_extraction:
|
|
26
|
+
yield_pattern:
|
|
27
|
+
match:
|
|
28
|
+
id: &id001
|
|
29
|
+
from: frontmatter_field
|
|
30
|
+
path:
|
|
31
|
+
- id
|
|
32
|
+
required: true
|
|
33
|
+
title: &id002
|
|
34
|
+
from: frontmatter_field
|
|
35
|
+
path:
|
|
36
|
+
- title
|
|
37
|
+
required: true
|
|
38
|
+
type: &id003
|
|
39
|
+
from: frontmatter_field
|
|
40
|
+
path:
|
|
41
|
+
- type
|
|
42
|
+
required: true
|
|
43
|
+
flow:
|
|
44
|
+
from: code_block
|
|
45
|
+
after_heading: Flow
|
|
46
|
+
required: true
|
|
47
|
+
language: mermaid
|
|
48
|
+
- name: permission
|
|
49
|
+
allowed_links:
|
|
50
|
+
grants: [scope]
|
|
51
|
+
guards: [externally-exposed]
|
|
52
|
+
references: [role]
|
|
53
|
+
data_schema:
|
|
54
|
+
type: object
|
|
55
|
+
body_extraction:
|
|
56
|
+
yield_pattern:
|
|
57
|
+
match:
|
|
58
|
+
id: *id001
|
|
59
|
+
title: *id002
|
|
60
|
+
type: *id003
|
|
61
|
+
resource:
|
|
62
|
+
from: frontmatter_field
|
|
63
|
+
path:
|
|
64
|
+
- resource
|
|
65
|
+
required: true
|
|
66
|
+
verb:
|
|
67
|
+
from: frontmatter_field
|
|
68
|
+
path:
|
|
69
|
+
- verb
|
|
70
|
+
required: true
|
|
71
|
+
- name: scope
|
|
72
|
+
allowed_links:
|
|
73
|
+
references: [permission]
|
|
74
|
+
data_schema:
|
|
75
|
+
type: object
|
|
76
|
+
body_extraction:
|
|
77
|
+
yield_pattern:
|
|
78
|
+
match:
|
|
79
|
+
id: *id001
|
|
80
|
+
title: *id002
|
|
81
|
+
type: *id003
|
|
82
|
+
grants:
|
|
83
|
+
from: section_body
|
|
84
|
+
after_heading: Grants
|
|
85
|
+
required: true
|
|
86
|
+
- name: role
|
|
87
|
+
allowed_links:
|
|
88
|
+
grants: [permission]
|
|
89
|
+
references: [role]
|
|
90
|
+
data_schema:
|
|
91
|
+
type: object
|
|
92
|
+
body_extraction:
|
|
93
|
+
yield_pattern:
|
|
94
|
+
match:
|
|
95
|
+
id: *id001
|
|
96
|
+
title: *id002
|
|
97
|
+
type: *id003
|
|
98
|
+
permissions:
|
|
99
|
+
from: section_body
|
|
100
|
+
after_heading: Permissions
|
|
101
|
+
required: true
|
|
102
|
+
- name: secret
|
|
103
|
+
roles: [sensitive]
|
|
104
|
+
allowed_links:
|
|
105
|
+
references: [secret]
|
|
106
|
+
data_schema:
|
|
107
|
+
type: object
|
|
108
|
+
body_extraction:
|
|
109
|
+
yield_pattern:
|
|
110
|
+
match:
|
|
111
|
+
id: *id001
|
|
112
|
+
title: *id002
|
|
113
|
+
type: *id003
|
|
114
|
+
rotation:
|
|
115
|
+
from: section_body
|
|
116
|
+
after_heading: Rotation
|
|
117
|
+
required: true
|
|
118
|
+
- name: encryption_key
|
|
119
|
+
roles: [sensitive]
|
|
120
|
+
allowed_links:
|
|
121
|
+
encrypts: [sensitive, data_classification]
|
|
122
|
+
data_schema:
|
|
123
|
+
type: object
|
|
124
|
+
body_extraction:
|
|
125
|
+
yield_pattern:
|
|
126
|
+
match:
|
|
127
|
+
id: *id001
|
|
128
|
+
title: *id002
|
|
129
|
+
type: *id003
|
|
130
|
+
algorithm:
|
|
131
|
+
from: frontmatter_field
|
|
132
|
+
path:
|
|
133
|
+
- algorithm
|
|
134
|
+
required: true
|
|
135
|
+
rotation:
|
|
136
|
+
from: frontmatter_field
|
|
137
|
+
path:
|
|
138
|
+
- rotation
|
|
139
|
+
required: false
|
|
140
|
+
- name: session_config
|
|
141
|
+
allowed_links:
|
|
142
|
+
references: [auth_flow, jwt_claim]
|
|
143
|
+
data_schema:
|
|
144
|
+
type: object
|
|
145
|
+
body_extraction:
|
|
146
|
+
yield_pattern:
|
|
147
|
+
match:
|
|
148
|
+
id: *id001
|
|
149
|
+
title: *id002
|
|
150
|
+
type: *id003
|
|
151
|
+
settings:
|
|
152
|
+
from: section_body
|
|
153
|
+
after_heading: Settings
|
|
154
|
+
required: true
|
|
155
|
+
- name: data_classification
|
|
156
|
+
allowed_links:
|
|
157
|
+
classifies: [persistable, externally-exposed, sensitive]
|
|
158
|
+
references: [data_classification]
|
|
159
|
+
data_schema:
|
|
160
|
+
type: object
|
|
161
|
+
body_extraction:
|
|
162
|
+
yield_pattern:
|
|
163
|
+
match:
|
|
164
|
+
id: *id001
|
|
165
|
+
title: *id002
|
|
166
|
+
type: *id003
|
|
167
|
+
handling:
|
|
168
|
+
from: section_body
|
|
169
|
+
after_heading: Handling
|
|
170
|
+
required: true
|
|
171
|
+
- name: trust_boundary
|
|
172
|
+
allowed_links:
|
|
173
|
+
contains: [asset, api_endpoint]
|
|
174
|
+
references: [trust_boundary]
|
|
175
|
+
data_schema:
|
|
176
|
+
type: object
|
|
177
|
+
body_extraction:
|
|
178
|
+
yield_pattern:
|
|
179
|
+
match:
|
|
180
|
+
id: *id001
|
|
181
|
+
title: *id002
|
|
182
|
+
type: *id003
|
|
183
|
+
boundary:
|
|
184
|
+
from: code_block
|
|
185
|
+
after_heading: Boundary
|
|
186
|
+
required: true
|
|
187
|
+
language: mermaid
|
|
188
|
+
- name: audit_event
|
|
189
|
+
roles: [event-like]
|
|
190
|
+
allowed_links:
|
|
191
|
+
references: [audit_event]
|
|
192
|
+
data_schema:
|
|
193
|
+
type: object
|
|
194
|
+
body_extraction:
|
|
195
|
+
yield_pattern:
|
|
196
|
+
match:
|
|
197
|
+
id: *id001
|
|
198
|
+
title: *id002
|
|
199
|
+
type: *id003
|
|
200
|
+
event_schema:
|
|
201
|
+
from: code_block
|
|
202
|
+
after_heading: Event Schema
|
|
203
|
+
required: true
|
|
204
|
+
language: json
|
|
205
|
+
- name: csrf_token
|
|
206
|
+
roles: [sensitive]
|
|
207
|
+
allowed_links:
|
|
208
|
+
references: [csrf_token]
|
|
209
|
+
data_schema:
|
|
210
|
+
type: object
|
|
211
|
+
body_extraction:
|
|
212
|
+
yield_pattern:
|
|
213
|
+
match:
|
|
214
|
+
id: *id001
|
|
215
|
+
title: *id002
|
|
216
|
+
type: *id003
|
|
217
|
+
rotation_window:
|
|
218
|
+
from: frontmatter_field
|
|
219
|
+
path:
|
|
220
|
+
- rotation_window
|
|
221
|
+
required: true
|
|
222
|
+
- name: cors_policy
|
|
223
|
+
allowed_links:
|
|
224
|
+
references: [cors_policy]
|
|
225
|
+
data_schema:
|
|
226
|
+
type: object
|
|
227
|
+
body_extraction:
|
|
228
|
+
yield_pattern:
|
|
229
|
+
match:
|
|
230
|
+
id: *id001
|
|
231
|
+
title: *id002
|
|
232
|
+
type: *id003
|
|
233
|
+
origins:
|
|
234
|
+
from: section_body
|
|
235
|
+
after_heading: Origins
|
|
236
|
+
required: true
|
|
237
|
+
- name: password_policy
|
|
238
|
+
allowed_links:
|
|
239
|
+
references: [password_policy]
|
|
240
|
+
data_schema:
|
|
241
|
+
type: object
|
|
242
|
+
body_extraction:
|
|
243
|
+
yield_pattern:
|
|
244
|
+
match:
|
|
245
|
+
id: *id001
|
|
246
|
+
title: *id002
|
|
247
|
+
type: *id003
|
|
248
|
+
rules:
|
|
249
|
+
from: section_body
|
|
250
|
+
after_heading: Rules
|
|
251
|
+
required: true
|
|
252
|
+
- name: mfa_method
|
|
253
|
+
allowed_links:
|
|
254
|
+
references: [mfa_method]
|
|
255
|
+
data_schema:
|
|
256
|
+
type: object
|
|
257
|
+
body_extraction:
|
|
258
|
+
yield_pattern:
|
|
259
|
+
match:
|
|
260
|
+
id: *id001
|
|
261
|
+
title: *id002
|
|
262
|
+
type: *id003
|
|
263
|
+
kind:
|
|
264
|
+
from: frontmatter_field
|
|
265
|
+
path:
|
|
266
|
+
- kind
|
|
267
|
+
required: true
|
|
268
|
+
factor:
|
|
269
|
+
from: frontmatter_field
|
|
270
|
+
path:
|
|
271
|
+
- factor
|
|
272
|
+
required: false
|
|
273
|
+
- name: jwt_claim
|
|
274
|
+
roles: [sensitive]
|
|
275
|
+
allowed_links:
|
|
276
|
+
references: [jwt_claim]
|
|
277
|
+
data_schema:
|
|
278
|
+
type: object
|
|
279
|
+
body_extraction:
|
|
280
|
+
yield_pattern:
|
|
281
|
+
match:
|
|
282
|
+
id: *id001
|
|
283
|
+
title: *id002
|
|
284
|
+
type: *id003
|
|
285
|
+
schema_json:
|
|
286
|
+
from: code_block
|
|
287
|
+
after_heading: Schema
|
|
288
|
+
required: true
|
|
289
|
+
language: json
|
|
290
|
+
- name: threat
|
|
291
|
+
allowed_links:
|
|
292
|
+
threatens: [asset, attack_surface]
|
|
293
|
+
exploits: [vulnerability]
|
|
294
|
+
data_schema:
|
|
295
|
+
type: object
|
|
296
|
+
body_extraction:
|
|
297
|
+
yield_pattern:
|
|
298
|
+
match:
|
|
299
|
+
id: &id004
|
|
300
|
+
from: frontmatter_field
|
|
301
|
+
path:
|
|
302
|
+
- id
|
|
303
|
+
required: true
|
|
304
|
+
title: &id005
|
|
305
|
+
from: frontmatter_field
|
|
306
|
+
path:
|
|
307
|
+
- title
|
|
308
|
+
required: true
|
|
309
|
+
type: &id006
|
|
310
|
+
from: frontmatter_field
|
|
311
|
+
path:
|
|
312
|
+
- type
|
|
313
|
+
required: true
|
|
314
|
+
stride_category:
|
|
315
|
+
from: frontmatter_field
|
|
316
|
+
path:
|
|
317
|
+
- stride_category
|
|
318
|
+
required: true
|
|
319
|
+
vector:
|
|
320
|
+
from: frontmatter_field
|
|
321
|
+
path:
|
|
322
|
+
- vector
|
|
323
|
+
required: true
|
|
324
|
+
- name: control
|
|
325
|
+
allowed_links:
|
|
326
|
+
mitigates: [threat, risk, vulnerability]
|
|
327
|
+
implements: [policy]
|
|
328
|
+
protects: [externally-exposed, asset]
|
|
329
|
+
data_schema:
|
|
330
|
+
type: object
|
|
331
|
+
body_extraction:
|
|
332
|
+
yield_pattern:
|
|
333
|
+
match:
|
|
334
|
+
id: *id004
|
|
335
|
+
title: *id005
|
|
336
|
+
type: *id006
|
|
337
|
+
mappings:
|
|
338
|
+
from: section_body
|
|
339
|
+
after_heading: Mappings
|
|
340
|
+
required: true
|
|
341
|
+
- name: risk
|
|
342
|
+
allowed_links:
|
|
343
|
+
arises_from: [threat, vulnerability]
|
|
344
|
+
references: [asset]
|
|
345
|
+
data_schema:
|
|
346
|
+
type: object
|
|
347
|
+
body_extraction:
|
|
348
|
+
yield_pattern:
|
|
349
|
+
match:
|
|
350
|
+
id: *id004
|
|
351
|
+
title: *id005
|
|
352
|
+
type: *id006
|
|
353
|
+
likelihood:
|
|
354
|
+
from: frontmatter_field
|
|
355
|
+
path:
|
|
356
|
+
- likelihood
|
|
357
|
+
required: true
|
|
358
|
+
impact:
|
|
359
|
+
from: frontmatter_field
|
|
360
|
+
path:
|
|
361
|
+
- impact
|
|
362
|
+
required: true
|
|
363
|
+
- name: vulnerability
|
|
364
|
+
allowed_links:
|
|
365
|
+
affects: [asset, attack_surface]
|
|
366
|
+
references: [vulnerability]
|
|
367
|
+
data_schema:
|
|
368
|
+
type: object
|
|
369
|
+
body_extraction:
|
|
370
|
+
yield_pattern:
|
|
371
|
+
match:
|
|
372
|
+
id: *id004
|
|
373
|
+
title: *id005
|
|
374
|
+
type: *id006
|
|
375
|
+
cve_id:
|
|
376
|
+
from: frontmatter_field
|
|
377
|
+
path:
|
|
378
|
+
- cve_id
|
|
379
|
+
required: false
|
|
380
|
+
severity:
|
|
381
|
+
from: frontmatter_field
|
|
382
|
+
path:
|
|
383
|
+
- severity
|
|
384
|
+
required: true
|
|
385
|
+
- name: asset
|
|
386
|
+
allowed_links:
|
|
387
|
+
references: [data_classification, trust_boundary]
|
|
388
|
+
data_schema:
|
|
389
|
+
type: object
|
|
390
|
+
body_extraction:
|
|
391
|
+
yield_pattern:
|
|
392
|
+
match:
|
|
393
|
+
id: *id004
|
|
394
|
+
title: *id005
|
|
395
|
+
type: *id006
|
|
396
|
+
description_body:
|
|
397
|
+
from: section_body
|
|
398
|
+
after_heading: Description
|
|
399
|
+
required: true
|
|
400
|
+
- name: attack_surface
|
|
401
|
+
roles: [externally-exposed]
|
|
402
|
+
allowed_links:
|
|
403
|
+
exposes: [asset, api_endpoint]
|
|
404
|
+
data_schema:
|
|
405
|
+
type: object
|
|
406
|
+
body_extraction:
|
|
407
|
+
yield_pattern:
|
|
408
|
+
match:
|
|
409
|
+
id: *id004
|
|
410
|
+
title: *id005
|
|
411
|
+
type: *id006
|
|
412
|
+
entry_points:
|
|
413
|
+
from: section_body
|
|
414
|
+
after_heading: Entry Points
|
|
415
|
+
required: true
|
|
416
|
+
- name: policy
|
|
417
|
+
allowed_links:
|
|
418
|
+
governs: [control, role, permission, data_classification]
|
|
419
|
+
data_schema:
|
|
420
|
+
type: object
|
|
421
|
+
body_extraction:
|
|
422
|
+
yield_pattern:
|
|
423
|
+
match:
|
|
424
|
+
id: *id004
|
|
425
|
+
title: *id005
|
|
426
|
+
type: *id006
|
|
427
|
+
policy_body:
|
|
428
|
+
from: section_body
|
|
429
|
+
after_heading: Policy
|
|
430
|
+
required: true
|
|
431
|
+
- name: audit_finding
|
|
432
|
+
allowed_links:
|
|
433
|
+
traces_to: [risk]
|
|
434
|
+
references: [control, vulnerability, asset]
|
|
435
|
+
data_schema:
|
|
436
|
+
type: object
|
|
437
|
+
body_extraction:
|
|
438
|
+
yield_pattern:
|
|
439
|
+
match:
|
|
440
|
+
id: *id004
|
|
441
|
+
title: *id005
|
|
442
|
+
type: *id006
|
|
443
|
+
recommendation:
|
|
444
|
+
from: section_body
|
|
445
|
+
after_heading: Recommendation
|
|
446
|
+
required: true
|
|
447
|
+
|
|
448
|
+
# FR-043: concrete-term lexicon — security / identity / auth objects.
|
|
449
|
+
lexicon:
|
|
450
|
+
token: {definition: a bearer credential representing identity or grant}
|
|
451
|
+
secret: {definition: a confidential value (key, password) kept out of code}
|
|
452
|
+
scope: {definition: a named permission boundary on a grant}
|
|
453
|
+
claim: {definition: an assertion carried in a token}
|
|
454
|
+
permission: {definition: an allowed action on a resource}
|
|
455
|
+
credential: {definition: data proving an identity}
|
|
456
|
+
certificate: {definition: a signed binding of identity to a public key}
|
|
457
|
+
signature: {definition: a cryptographic proof of integrity/origin}
|
|
458
|
+
principal: {definition: an authenticated identity (user/service)}
|
|
459
|
+
keypair: {definition: a public/private cryptographic key pair}
|
|
460
|
+
nonce: {definition: a single-use value preventing replay}
|
|
461
|
+
hash: {definition: a fixed-size digest of input}
|
|
462
|
+
cipher: {definition: an encryption/decryption algorithm}
|
|
463
|
+
audit: {definition: a recorded, tamper-evident event trail}
|
|
464
|
+
policy: {definition: a declarative rule governing access or behavior}
|
package/package.json
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@agent-ix/spec-objects-security",
|
|
3
|
+
"version": "0.4.0",
|
|
4
|
+
"description": "Filament Module: tier-2 security and identity ObjectTypes (threat, control, risk, asset, policy, auth_flow, role, scope, jwt_claim, secret)",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "Agent IX <agents@agent-ix.dev>",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"agent-ix",
|
|
9
|
+
"filament",
|
|
10
|
+
"filament-module",
|
|
11
|
+
"quoin",
|
|
12
|
+
"quire",
|
|
13
|
+
"spec"
|
|
14
|
+
],
|
|
15
|
+
"files": [
|
|
16
|
+
"manifest.yaml",
|
|
17
|
+
"schemas/",
|
|
18
|
+
"skeletons/",
|
|
19
|
+
"README.md",
|
|
20
|
+
"LICENSE"
|
|
21
|
+
],
|
|
22
|
+
"scripts": {
|
|
23
|
+
"prepack": "node scripts/stage-npm.mjs"
|
|
24
|
+
},
|
|
25
|
+
"publishConfig": {
|
|
26
|
+
"registry": "https://registry.npmjs.org/",
|
|
27
|
+
"access": "public"
|
|
28
|
+
},
|
|
29
|
+
"repository": {
|
|
30
|
+
"type": "git",
|
|
31
|
+
"url": "git+https://github.com/agent-ix/spec-objects-security.git"
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: ASSET-001
|
|
3
|
+
title: "Session store"
|
|
4
|
+
type: asset
|
|
5
|
+
---
|
|
6
|
+
<!-- asset authoring skeleton (spec-objects-security). Fill every part with
|
|
7
|
+
substantive content. Contract (manifest body_extraction asserts):
|
|
8
|
+
- Frontmatter MUST carry id, title, type (type: asset).
|
|
9
|
+
- A "Description" section MUST describe the asset and why it matters. -->
|
|
10
|
+
# [ASSET-001] Session store
|
|
11
|
+
|
|
12
|
+
Redis cluster holding all active Atlas web sessions and CSRF token state.
|
|
13
|
+
|
|
14
|
+
## Description
|
|
15
|
+
|
|
16
|
+
The session store is the authority for who is currently authenticated:
|
|
17
|
+
compromise yields the ability to mint or hijack any active session across all
|
|
18
|
+
tenants, bypassing AUTHFLOW-001 entirely. It runs in the trusted private
|
|
19
|
+
subnet behind BOUND-001, accepts only mTLS connections from the auth service,
|
|
20
|
+
and persists nothing to disk (RDB/AOF disabled) so session identifiers never
|
|
21
|
+
reach backup media. Data it holds is classified Confidential (CLASS-001
|
|
22
|
+
handling applies to the embedded user identifiers).
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: SURF-001
|
|
3
|
+
title: "Atlas authentication attack surface"
|
|
4
|
+
type: attack_surface
|
|
5
|
+
---
|
|
6
|
+
<!-- attack_surface authoring skeleton (spec-objects-security). Fill every part
|
|
7
|
+
with substantive content. Contract (manifest body_extraction asserts):
|
|
8
|
+
- Frontmatter MUST carry id, title, type (type:
|
|
9
|
+
attack_surface).
|
|
10
|
+
- An "Entry Points" section MUST enumerate the externally reachable
|
|
11
|
+
entry points. -->
|
|
12
|
+
# [SURF-001] Atlas authentication attack surface
|
|
13
|
+
|
|
14
|
+
Internet-reachable surface of the Atlas authentication subsystem, reviewed
|
|
15
|
+
whenever a new route crosses BOUND-001 outward.
|
|
16
|
+
|
|
17
|
+
## Entry Points
|
|
18
|
+
|
|
19
|
+
- `GET /login`, `GET /callback` — browser OIDC endpoints (AUTHFLOW-001)
|
|
20
|
+
- `POST /api/token` — public API token exchange for integrations (SCOPE-001)
|
|
21
|
+
- `POST /auth/local` — break-glass local login, gated by PASSPOL-001 and
|
|
22
|
+
MFA-001
|
|
23
|
+
- `POST /webhooks/idp` — IdP back-channel logout receiver, HMAC-verified
|
|
24
|
+
- Session cookie and `X-Atlas-CSRF` header parsing in the gateway middleware
|
|
25
|
+
(CSRF-001), reachable from any authenticated page
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: AUDIT-001
|
|
3
|
+
title: "user.login.succeeded audit event"
|
|
4
|
+
type: audit_event
|
|
5
|
+
---
|
|
6
|
+
<!-- audit_event authoring skeleton (spec-objects-security). Fill every part
|
|
7
|
+
with substantive content. Contract (manifest body_extraction asserts):
|
|
8
|
+
- Frontmatter MUST carry id, title, type (type:
|
|
9
|
+
audit_event).
|
|
10
|
+
- An "Event Schema" section MUST carry a ```json code block with the
|
|
11
|
+
event's payload schema. -->
|
|
12
|
+
# [AUDIT-001] user.login.succeeded audit event
|
|
13
|
+
|
|
14
|
+
Emitted by the auth service when AUTHFLOW-001 completes and a session is
|
|
15
|
+
established. Appended to the tenant's immutable audit stream and queryable by
|
|
16
|
+
ROLE-001 (Tenant Auditor) holders.
|
|
17
|
+
|
|
18
|
+
## Event Schema
|
|
19
|
+
|
|
20
|
+
```json
|
|
21
|
+
{
|
|
22
|
+
"type": "object",
|
|
23
|
+
"required": ["event", "occurred_at", "tenant_id", "user_id", "source_ip"],
|
|
24
|
+
"properties": {
|
|
25
|
+
"event": { "const": "user.login.succeeded" },
|
|
26
|
+
"occurred_at": { "type": "string", "format": "date-time" },
|
|
27
|
+
"tenant_id": { "type": "string", "format": "uuid" },
|
|
28
|
+
"user_id": { "type": "string", "format": "uuid" },
|
|
29
|
+
"source_ip": { "type": "string" },
|
|
30
|
+
"idp_issuer": { "type": "string", "format": "uri" },
|
|
31
|
+
"mfa_method": { "type": "string", "enum": ["totp", "webauthn", "none"] }
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
```
|