@intentius/chant-lexicon-cedar 0.44.8

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.
Files changed (265) hide show
  1. package/README.md +190 -0
  2. package/dist/avp/ambient.d.ts +54 -0
  3. package/dist/avp/ambient.d.ts.map +1 -0
  4. package/dist/avp/client.d.ts +127 -0
  5. package/dist/avp/client.d.ts.map +1 -0
  6. package/dist/avp/describe-resources.d.ts +42 -0
  7. package/dist/avp/describe-resources.d.ts.map +1 -0
  8. package/dist/avp/embed.d.ts +120 -0
  9. package/dist/avp/embed.d.ts.map +1 -0
  10. package/dist/avp/live-export.d.ts +94 -0
  11. package/dist/avp/live-export.d.ts.map +1 -0
  12. package/dist/avp/ownership.d.ts +97 -0
  13. package/dist/avp/ownership.d.ts.map +1 -0
  14. package/dist/avp/statement.d.ts +22 -0
  15. package/dist/avp/statement.d.ts.map +1 -0
  16. package/dist/avp/store.d.ts +82 -0
  17. package/dist/avp/store.d.ts.map +1 -0
  18. package/dist/avp/testdata/mock-transport.d.ts +55 -0
  19. package/dist/avp/testdata/mock-transport.d.ts.map +1 -0
  20. package/dist/codegen/docs-cli.d.ts +3 -0
  21. package/dist/codegen/docs-cli.d.ts.map +1 -0
  22. package/dist/codegen/docs.d.ts +26 -0
  23. package/dist/codegen/docs.d.ts.map +1 -0
  24. package/dist/codegen/emit.d.ts +85 -0
  25. package/dist/codegen/emit.d.ts.map +1 -0
  26. package/dist/codegen/generate-cli.d.ts +3 -0
  27. package/dist/codegen/generate-cli.d.ts.map +1 -0
  28. package/dist/codegen/generate.d.ts +37 -0
  29. package/dist/codegen/generate.d.ts.map +1 -0
  30. package/dist/codegen/naming.d.ts +48 -0
  31. package/dist/codegen/naming.d.ts.map +1 -0
  32. package/dist/codegen/package.d.ts +10 -0
  33. package/dist/codegen/package.d.ts.map +1 -0
  34. package/dist/composites/deny-by-default-set.d.ts +58 -0
  35. package/dist/composites/deny-by-default-set.d.ts.map +1 -0
  36. package/dist/composites/index.d.ts +12 -0
  37. package/dist/composites/index.d.ts.map +1 -0
  38. package/dist/composites/owner-can-manage.d.ts +48 -0
  39. package/dist/composites/owner-can-manage.d.ts.map +1 -0
  40. package/dist/config.d.ts +102 -0
  41. package/dist/config.d.ts.map +1 -0
  42. package/dist/coverage.d.ts +59 -0
  43. package/dist/coverage.d.ts.map +1 -0
  44. package/dist/detect.d.ts +18 -0
  45. package/dist/detect.d.ts.map +1 -0
  46. package/dist/generated/index.d.ts +251 -0
  47. package/dist/generated/index.d.ts.map +1 -0
  48. package/dist/generated/runtime.d.ts +2 -0
  49. package/dist/generated/runtime.d.ts.map +1 -0
  50. package/dist/import/adapter.d.ts +21 -0
  51. package/dist/import/adapter.d.ts.map +1 -0
  52. package/dist/import/clause-text.d.ts +38 -0
  53. package/dist/import/clause-text.d.ts.map +1 -0
  54. package/dist/import/generator.d.ts +53 -0
  55. package/dist/import/generator.d.ts.map +1 -0
  56. package/dist/import/parser.d.ts +57 -0
  57. package/dist/import/parser.d.ts.map +1 -0
  58. package/dist/index.d.ts +34 -0
  59. package/dist/index.d.ts.map +1 -0
  60. package/dist/init-templates.d.ts +32 -0
  61. package/dist/init-templates.d.ts.map +1 -0
  62. package/dist/integrity.json +22 -0
  63. package/dist/lint/audit-catalog.d.ts +29 -0
  64. package/dist/lint/audit-catalog.d.ts.map +1 -0
  65. package/dist/lint/post-synth/cedar-helpers.d.ts +97 -0
  66. package/dist/lint/post-synth/cedar-helpers.d.ts.map +1 -0
  67. package/dist/lint/post-synth/cedc010.d.ts +17 -0
  68. package/dist/lint/post-synth/cedc010.d.ts.map +1 -0
  69. package/dist/lint/post-synth/cedc011.d.ts +17 -0
  70. package/dist/lint/post-synth/cedc011.d.ts.map +1 -0
  71. package/dist/lint/post-synth/cedc012.d.ts +21 -0
  72. package/dist/lint/post-synth/cedc012.d.ts.map +1 -0
  73. package/dist/lint/post-synth/cedc013.d.ts +20 -0
  74. package/dist/lint/post-synth/cedc013.d.ts.map +1 -0
  75. package/dist/lint/post-synth/cedc014.d.ts +19 -0
  76. package/dist/lint/post-synth/cedc014.d.ts.map +1 -0
  77. package/dist/lint/post-synth/cede010.d.ts +34 -0
  78. package/dist/lint/post-synth/cede010.d.ts.map +1 -0
  79. package/dist/lint/post-synth/cede011.d.ts +22 -0
  80. package/dist/lint/post-synth/cede011.d.ts.map +1 -0
  81. package/dist/lint/post-synth/ceds010.d.ts +24 -0
  82. package/dist/lint/post-synth/ceds010.d.ts.map +1 -0
  83. package/dist/lint/post-synth/ceds011.d.ts +19 -0
  84. package/dist/lint/post-synth/ceds011.d.ts.map +1 -0
  85. package/dist/lint/post-synth/ceds012.d.ts +17 -0
  86. package/dist/lint/post-synth/ceds012.d.ts.map +1 -0
  87. package/dist/lint/post-synth/index.d.ts +3 -0
  88. package/dist/lint/post-synth/index.d.ts.map +1 -0
  89. package/dist/lint/post-synth/wasm-helpers.d.ts +108 -0
  90. package/dist/lint/post-synth/wasm-helpers.d.ts.map +1 -0
  91. package/dist/lint/rules/index.d.ts +10 -0
  92. package/dist/lint/rules/index.d.ts.map +1 -0
  93. package/dist/lint/rules/policy-shape.d.ts +31 -0
  94. package/dist/lint/rules/policy-shape.d.ts.map +1 -0
  95. package/dist/lsp/completions.d.ts +24 -0
  96. package/dist/lsp/completions.d.ts.map +1 -0
  97. package/dist/lsp/hover.d.ts +11 -0
  98. package/dist/lsp/hover.d.ts.map +1 -0
  99. package/dist/lsp/registry.d.ts +45 -0
  100. package/dist/lsp/registry.d.ts.map +1 -0
  101. package/dist/manifest.json +8 -0
  102. package/dist/mcp/index.d.ts +34 -0
  103. package/dist/mcp/index.d.ts.map +1 -0
  104. package/dist/mcp/policy-coverage.d.ts +81 -0
  105. package/dist/mcp/policy-coverage.d.ts.map +1 -0
  106. package/dist/meta.json +699 -0
  107. package/dist/okf/index.md +37 -0
  108. package/dist/okf/rules/CEDC001.md +11 -0
  109. package/dist/okf/rules/CEDC010.md +11 -0
  110. package/dist/okf/rules/CEDC011.md +15 -0
  111. package/dist/okf/rules/CEDC012.md +11 -0
  112. package/dist/okf/rules/CEDC013.md +15 -0
  113. package/dist/okf/rules/CEDC014.md +15 -0
  114. package/dist/okf/rules/CEDE010.md +15 -0
  115. package/dist/okf/rules/CEDE011.md +15 -0
  116. package/dist/okf/rules/CEDS010.md +15 -0
  117. package/dist/okf/rules/CEDS011.md +11 -0
  118. package/dist/okf/rules/CEDS012.md +15 -0
  119. package/dist/okf/types/AdminAction.md +14 -0
  120. package/dist/okf/types/Application.md +14 -0
  121. package/dist/okf/types/ApproveAction.md +13 -0
  122. package/dist/okf/types/CommentAction.md +14 -0
  123. package/dist/okf/types/CreateAction.md +14 -0
  124. package/dist/okf/types/DeleteAction.md +14 -0
  125. package/dist/okf/types/Document.md +18 -0
  126. package/dist/okf/types/Folder.md +15 -0
  127. package/dist/okf/types/Group.md +14 -0
  128. package/dist/okf/types/ListAction.md +14 -0
  129. package/dist/okf/types/Policy.md +29 -0
  130. package/dist/okf/types/ReadAction.md +14 -0
  131. package/dist/okf/types/ServiceAccount.md +15 -0
  132. package/dist/okf/types/ShareAction.md +14 -0
  133. package/dist/okf/types/Team.md +14 -0
  134. package/dist/okf/types/User.md +18 -0
  135. package/dist/okf/types/WriteAction.md +14 -0
  136. package/dist/package-cli.d.ts +3 -0
  137. package/dist/package-cli.d.ts.map +1 -0
  138. package/dist/plugin.d.ts +8 -0
  139. package/dist/plugin.d.ts.map +1 -0
  140. package/dist/rules/cedar-helpers.ts +209 -0
  141. package/dist/rules/cedc010.ts +80 -0
  142. package/dist/rules/cedc011.ts +47 -0
  143. package/dist/rules/cedc012.ts +64 -0
  144. package/dist/rules/cedc013.ts +68 -0
  145. package/dist/rules/cedc014.ts +73 -0
  146. package/dist/rules/cede010.ts +89 -0
  147. package/dist/rules/cede011.ts +58 -0
  148. package/dist/rules/ceds010.ts +57 -0
  149. package/dist/rules/ceds011.ts +42 -0
  150. package/dist/rules/ceds012.ts +50 -0
  151. package/dist/rules/policy-shape.ts +148 -0
  152. package/dist/rules/wasm-helpers.ts +315 -0
  153. package/dist/serializer.d.ts +138 -0
  154. package/dist/serializer.d.ts.map +1 -0
  155. package/dist/spec/fetch.d.ts +71 -0
  156. package/dist/spec/fetch.d.ts.map +1 -0
  157. package/dist/spec/parse.d.ts +113 -0
  158. package/dist/spec/parse.d.ts.map +1 -0
  159. package/dist/spec/pin.d.ts +116 -0
  160. package/dist/spec/pin.d.ts.map +1 -0
  161. package/dist/spec/pinned-names.json +18 -0
  162. package/dist/spec/wasm.d.ts +143 -0
  163. package/dist/spec/wasm.d.ts.map +1 -0
  164. package/dist/types/index.d.ts +219 -0
  165. package/dist/validate-cli.d.ts +3 -0
  166. package/dist/validate-cli.d.ts.map +1 -0
  167. package/dist/validate.d.ts +25 -0
  168. package/dist/validate.d.ts.map +1 -0
  169. package/package.json +75 -0
  170. package/src/avp/OWNERSHIP.md +125 -0
  171. package/src/avp/ambient.test.ts +113 -0
  172. package/src/avp/ambient.ts +124 -0
  173. package/src/avp/client.ts +310 -0
  174. package/src/avp/describe-resources.test.ts +316 -0
  175. package/src/avp/describe-resources.ts +215 -0
  176. package/src/avp/embed.test.ts +114 -0
  177. package/src/avp/embed.ts +190 -0
  178. package/src/avp/live-export.test.ts +232 -0
  179. package/src/avp/live-export.ts +185 -0
  180. package/src/avp/ownership.test.ts +101 -0
  181. package/src/avp/ownership.ts +170 -0
  182. package/src/avp/statement.ts +50 -0
  183. package/src/avp/store.ts +152 -0
  184. package/src/avp/testdata/mock-transport.ts +147 -0
  185. package/src/codegen/docs-cli.ts +7 -0
  186. package/src/codegen/docs.ts +873 -0
  187. package/src/codegen/emit.ts +496 -0
  188. package/src/codegen/generate-cli.ts +18 -0
  189. package/src/codegen/generate.test.ts +128 -0
  190. package/src/codegen/generate.ts +123 -0
  191. package/src/codegen/naming.ts +101 -0
  192. package/src/codegen/package.ts +52 -0
  193. package/src/composites/composites.test.ts +206 -0
  194. package/src/composites/deny-by-default-set.ts +98 -0
  195. package/src/composites/index.ts +13 -0
  196. package/src/composites/owner-can-manage.ts +80 -0
  197. package/src/config-namespace.test.ts +44 -0
  198. package/src/config.test.ts +82 -0
  199. package/src/config.ts +119 -0
  200. package/src/coverage.test.ts +61 -0
  201. package/src/coverage.ts +166 -0
  202. package/src/detect.test.ts +64 -0
  203. package/src/detect.ts +59 -0
  204. package/src/generated/index.d.ts +219 -0
  205. package/src/generated/index.ts +279 -0
  206. package/src/generated/lexicon-cedar.json +699 -0
  207. package/src/generated/runtime.ts +2 -0
  208. package/src/import/adapter.ts +63 -0
  209. package/src/import/clause-text.ts +178 -0
  210. package/src/import/generator.test.ts +133 -0
  211. package/src/import/generator.ts +219 -0
  212. package/src/import/parser.test.ts +265 -0
  213. package/src/import/parser.ts +352 -0
  214. package/src/import/roundtrip.test.ts +127 -0
  215. package/src/import/testdata/full.cedar +36 -0
  216. package/src/import/testdata/full.cedar.json +238 -0
  217. package/src/import/testdata/realistic.cedar +35 -0
  218. package/src/import/testdata/simple.cedar +6 -0
  219. package/src/index.ts +94 -0
  220. package/src/init-templates.test.ts +158 -0
  221. package/src/init-templates.ts +358 -0
  222. package/src/lint/audit-catalog.ts +130 -0
  223. package/src/lint/post-synth/cedar-helpers.ts +209 -0
  224. package/src/lint/post-synth/cedc010.ts +80 -0
  225. package/src/lint/post-synth/cedc011.ts +47 -0
  226. package/src/lint/post-synth/cedc012.ts +64 -0
  227. package/src/lint/post-synth/cedc013.ts +68 -0
  228. package/src/lint/post-synth/cedc014.ts +73 -0
  229. package/src/lint/post-synth/cede010.ts +89 -0
  230. package/src/lint/post-synth/cede011.ts +58 -0
  231. package/src/lint/post-synth/ceds010.ts +57 -0
  232. package/src/lint/post-synth/ceds011.ts +42 -0
  233. package/src/lint/post-synth/ceds012.ts +50 -0
  234. package/src/lint/post-synth/index.ts +25 -0
  235. package/src/lint/post-synth/post-synth.test.ts +474 -0
  236. package/src/lint/post-synth/wasm-helpers.ts +315 -0
  237. package/src/lint/rules/index.ts +12 -0
  238. package/src/lint/rules/policy-shape.test.ts +90 -0
  239. package/src/lint/rules/policy-shape.ts +148 -0
  240. package/src/lsp/completions.test.ts +111 -0
  241. package/src/lsp/completions.ts +55 -0
  242. package/src/lsp/hover.test.ts +82 -0
  243. package/src/lsp/hover.ts +75 -0
  244. package/src/lsp/registry.ts +74 -0
  245. package/src/mcp/index.ts +103 -0
  246. package/src/mcp/policy-coverage.test.ts +176 -0
  247. package/src/mcp/policy-coverage.ts +205 -0
  248. package/src/package-cli.ts +22 -0
  249. package/src/plugin.test.ts +115 -0
  250. package/src/plugin.ts +312 -0
  251. package/src/serializer.test.ts +502 -0
  252. package/src/serializer.ts +335 -0
  253. package/src/skills/chant-cedar-authoring.md +180 -0
  254. package/src/skills/chant-cedar-avp-embedding.md +125 -0
  255. package/src/skills/chant-cedar-meta-policy.md +119 -0
  256. package/src/spec/default-schema.cedarschema +108 -0
  257. package/src/spec/fetch.ts +107 -0
  258. package/src/spec/parse.test.ts +123 -0
  259. package/src/spec/parse.ts +253 -0
  260. package/src/spec/pin.test.ts +88 -0
  261. package/src/spec/pin.ts +243 -0
  262. package/src/spec/pinned-names.json +18 -0
  263. package/src/spec/wasm.ts +283 -0
  264. package/src/validate-cli.ts +8 -0
  265. package/src/validate.ts +85 -0
package/README.md ADDED
@@ -0,0 +1,190 @@
1
+ # @intentius/chant-lexicon-cedar
2
+
3
+ Cedar lexicon plugin for [chant](https://github.com/intentius/chant) — typed
4
+ authoring for [Cedar](https://www.cedarpolicy.com/) authorization policies.
5
+
6
+ Cedar has no variables, no modules and no loops, and its toolchain validates
7
+ and evaluates policies after they are written. Teams generate `.cedar` text
8
+ with string templating today. This lexicon is the typed authoring layer above
9
+ that text.
10
+
11
+ ## Status
12
+
13
+ Complete. The lexicon landed across the eight sub-issues of
14
+ INTENTIUS/chant#1645: the upstream pin (#1648), the scaffold and serializer
15
+ (#1649), schema-driven codegen (#1650), lint and post-synth validation through
16
+ `cedar-wasm` (#1651), AVP embedding and policy-store observation (#1652),
17
+ import/reconcile (#1653), the docs/LSP/MCP/skills/composites surface (#1654),
18
+ and CI/publishing onboarding (#1655).
19
+
20
+ ## The policy model
21
+
22
+ A policy is a `Cedar::Policy` entity whose props are:
23
+
24
+ | Prop | Meaning |
25
+ |------|---------|
26
+ | `effect` | `"permit"` or `"forbid"`; defaults to `permit` |
27
+ | `principal`, `action`, `resource` | scope constraints — `{}` for any, or `{ eq }`, `{ in }`, `{ is }` |
28
+ | `when`, `unless` | Cedar expression strings, one clause each |
29
+ | `annotations` | `Record<string, string>`, emitted as `@key("value")` |
30
+
31
+ The policy id comes from the export's logical name (`allowAdminRead` →
32
+ `allow-admin-read`) unless `annotations.id` sets one.
33
+
34
+ ## Where the types come from
35
+
36
+ `chant generate` reads a `.cedarschema` and emits a class per entity type, a
37
+ constant per action, and a UID type per entity — so `action: { eq: ReadAction }`
38
+ is checked at compile time and a renamed entity type is a compiler-guided
39
+ refactor.
40
+
41
+ Point it at your schema in `chant.config.ts`:
42
+
43
+ ```ts
44
+ import type { ChantConfig } from "@intentius/chant";
45
+ import "@intentius/chant-lexicon-cedar";
46
+
47
+ export default {
48
+ lexicons: ["cedar"],
49
+ cedar: { schema: "schema.cedarschema" },
50
+ } satisfies ChantConfig;
51
+ ```
52
+
53
+ `cedar.schema` defaults to `schema.cedarschema` in the project root. When
54
+ neither the configured path nor that default exists, generation falls back to
55
+ the small application-authorization schema bundled at
56
+ `src/spec/default-schema.cedarschema`, so a fresh checkout still produces a
57
+ surface. Set `cedar.validation.requireProjectSchema` to turn that fallback off
58
+ once your project has its own schema.
59
+
60
+ ## Pins
61
+
62
+ Two, for two different things:
63
+
64
+ - `CEDAR_WASM_VERSION` — the `@cedar-policy/cedar-wasm` package, bumped by the
65
+ weekly `cedar-upgrade` Op.
66
+ - `CEDAR_LANG_VERSION` — the Cedar *language* that package implements (4.5).
67
+ `generate()` asserts it before emitting anything, because a package bump that
68
+ leaves the language alone cannot change what parses.
69
+
70
+ Beside them, a content pin over the resolved JSON of the bundled default
71
+ schema. It moves when the schema is edited and — the case it exists for — when
72
+ a cedar-wasm upgrade resolves the same schema differently. Both rewrite the
73
+ generated types, and `src/generated/` is not committed.
74
+
75
+ ## Output
76
+
77
+ Serializing produces canonical `.cedar` policy text as the primary output and
78
+ a Cedar JSON policy set as `policies.cedar.json` beside it. Both are consumed
79
+ by any Cedar evaluator with chant nowhere in sight.
80
+
81
+ The JSON leg is built by handing the emitted text back to `cedar-wasm`, so
82
+ what lands on disk is Cedar's own reading of it — expression trees, not
83
+ expression source — and a policy carrying a `?principal`/`?resource` slot is
84
+ filed under `templates` rather than `staticPolicies` because Cedar, not this
85
+ serializer, decides which it is. Text the module cannot parse yields a build
86
+ warning and no JSON file, never an invalid one.
87
+
88
+ ## Import
89
+
90
+ `chant import` reads either surface back into TypeScript:
91
+
92
+ ```bash
93
+ chant import policies.cedar.json --output ./src
94
+ ```
95
+
96
+ The text leg round-trips byte-for-byte — `.cedar` → props → `new Policy({ … })`
97
+ → `.cedar` — because condition bodies are lifted out of the source verbatim and
98
+ then checked against the tree `cedar-wasm` makes of them. Two normalizations do
99
+ happen on the first lap and settle after it: annotations come back
100
+ alphabetically (they serialize into a sorted map), and interleaved
101
+ `when`/`unless` clauses regroup, since they are separate props.
102
+
103
+ Importing the JSON envelope instead has no source to quote, so its clauses come
104
+ back as the module renders them — semantically identical, defensively
105
+ parenthesized.
106
+
107
+ ## Composites
108
+
109
+ Cedar has nowhere to put a repeated policy shape, so the factories live here.
110
+
111
+ ```ts
112
+ import { OwnerCanManage, DenyByDefaultSet } from "@intentius/chant-lexicon-cedar";
113
+ ```
114
+
115
+ - `OwnerCanManage({ entityType, actions })` — a permit whose resource scope and
116
+ ownership guard arrive together.
117
+ - `DenyByDefaultSet({ policies, when })` — a guarded `forbid` floor and the
118
+ permits it governs, returned from one call so the floor cannot be dropped
119
+ alone. It throws on an empty `when`: an unguarded forbid overrides every
120
+ permit and authorizes nothing.
121
+
122
+ ## Agent surface
123
+
124
+ Three skills (`chant-cedar-authoring`, `chant-cedar-avp-embedding`, `chant-cedar-meta-policy`),
125
+ three `chant init` templates (`default`, `avp-embedding`,
126
+ `gateway-policy-set`), and three MCP contributions:
127
+
128
+ | Contribution | What it answers |
129
+ |---|---|
130
+ | `cedar:diff` | This build's policy set against the previous one |
131
+ | `chant://cedar/resource-catalog` | Every declaration generated from the schema |
132
+ | `cedar:coverage` | Which schema entity types and actions the policy set can apply to, which are reachable only from a `forbid`, and which no policy touches |
133
+
134
+ `cedar:coverage` resolves each policy through Cedar's own
135
+ `getValidRequestEnvsPolicy` rather than reading the scope literally, so action
136
+ groups, `is`, `in` and `appliesTo` are expanded by Cedar and not by a second,
137
+ worse implementation of it.
138
+
139
+ ## Amazon Verified Permissions
140
+
141
+ AVP is one evaluator among several, and the aws lexicon keeps the deployment
142
+ vehicle. What this lexicon adds is the typed statement inside it:
143
+ `avpPolicyDefinition(name, props)` returns exactly the `Definition` property
144
+ `AWS::VerifiedPermissions::Policy` takes, rendered by the same renderer that
145
+ writes the `.cedar` file — so the two cannot drift. There is deliberately **no
146
+ dependency on the aws lexicon**; the seam is the data shape. See
147
+ `examples/avp-embedding/`.
148
+
149
+ Beside the embedding, `describeResources()`, `observeAmbient()` and
150
+ `exportResources()` read a live policy store. `chant lifecycle diff --live`
151
+ reports declared policies that are missing from the store, and
152
+ `observeAmbient()` reports the reverse — policies in the store that no
153
+ declaration accounts for, which for an authorization store is a standing grant
154
+ nobody in the source tree can see.
155
+
156
+ The store is named by `CEDAR_AVP_POLICY_STORE_ID` (or
157
+ `CEDAR_AVP_POLICY_STORE_ID_<ENV>`), or by a `policyStoreId` prop on a declared
158
+ policy. AVP policy stores are taggable and individual policies are not, so
159
+ chant's per-policy ownership marker rides in the policy description — the
160
+ design record is `src/avp/OWNERSHIP.md`.
161
+
162
+ ## Commands
163
+
164
+ ```bash
165
+ just bundle # build dist/ (manifest, rules, integrity, OKF)
166
+ just test # run the lexicon's tests
167
+ just validate # check generated artifacts
168
+ just generate # schema-driven codegen from your .cedarschema
169
+
170
+ npm run docs # regenerate the docs site's pages + sidebar
171
+ npm run docs:build # build the Starlight site in docs/
172
+ ```
173
+
174
+ ## Project structure
175
+
176
+ - `src/plugin.ts` — LexiconPlugin with all lifecycle methods
177
+ - `src/serializer.ts` — `.cedar` text and JSON policy-set output
178
+ - `src/avp/` — AVP embedding, the policy-store readers, and the ownership channel
179
+ - `src/import/` — `chant import` parser, generator and round-trip fixtures
180
+ - `src/detect.ts` — which documents belong to this lexicon
181
+ - `src/codegen/` — code generation, docs, and packaging pipelines
182
+ - `src/spec/` — schema resolution, parsing, and the grammar pin
183
+ - `src/lint/rules/` — lint rules
184
+ - `src/lsp/` — LSP completions and hover over the generated registry
185
+ - `src/mcp/` — MCP tools and resources, including policy coverage
186
+ - `src/composites/` — `OwnerCanManage`, `DenyByDefaultSet`
187
+ - `src/skills/` — the three agent skills
188
+ - `src/init-templates.ts` — `chant init --lexicon cedar --template …`
189
+ - `src/generated/` — generated artifacts (do not edit)
190
+ - `docs/` — the standalone Starlight site, generated by `npm run docs`
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Policies that are simply *there* (#1652, chant #1278).
3
+ *
4
+ * For most lexicons ambient discovery is housekeeping — an unattached security
5
+ * group, an orphaned volume. For an authorization store it is a security
6
+ * finding. A policy in the store that no chant entity declares is a grant
7
+ * nobody in the source tree can see: it was added in the console, or by a
8
+ * previous tool, or by a teammate's script, and it is being evaluated on every
9
+ * request. `describeResources` structurally cannot report it, because it
10
+ * resolves outward from what was declared and this is precisely what was not.
11
+ *
12
+ * The reader reports the policy and its statement. It does not decide that an
13
+ * ambient `permit` is dangerous — that is a conclusion, and putting conclusions
14
+ * in observations is the mistake chant #1271 undid. What it does carry is the
15
+ * `effect`, because "which ambient policies are permits" is the first question
16
+ * anyone asks and re-parsing the statement to answer it is work every consumer
17
+ * would repeat.
18
+ */
19
+ import type { ResourceMetadata } from "@intentius/chant/lexicon";
20
+ import { type AvpClientOptions } from "./client.js";
21
+ /**
22
+ * The kinds this lexicon can enumerate beyond the declared estate.
23
+ *
24
+ * One, and it is the only kind cedar deploys. Declared separately from the
25
+ * reader so `chant search` can say `--ambient` is relevant to a policy query
26
+ * without paying for a scan to find out.
27
+ */
28
+ export declare const AVP_AMBIENT_KINDS: readonly string[];
29
+ export interface ObserveAvpAmbientOptions {
30
+ environment: string;
31
+ /** Entity types the project declares — the bound on what to enumerate. */
32
+ kinds: string[];
33
+ /** Already-observed managed resources, to exclude. */
34
+ observed: Record<string, ResourceMetadata>;
35
+ /** Cedar ids the project declares, so a declared-but-unobserved policy is not called ambient. */
36
+ declaredPolicyIds?: Iterable<string>;
37
+ policyStoreId?: string;
38
+ entities?: Map<string, {
39
+ entityType: string;
40
+ props: Record<string, unknown>;
41
+ }>;
42
+ client?: AvpClientOptions;
43
+ env?: Record<string, string | undefined>;
44
+ }
45
+ /**
46
+ * Policies in the store that nothing declares and nothing already observed.
47
+ *
48
+ * Best-effort by contract: ambient discovery is additive, and a failure here
49
+ * must not sink a managed observation that already succeeded, so the whole scan
50
+ * degrades to `{}` rather than throwing. The managed answer is complete without
51
+ * any of this.
52
+ */
53
+ export declare function observeAvpAmbient(options: ObserveAvpAmbientOptions): Promise<Record<string, ResourceMetadata>>;
54
+ //# sourceMappingURL=ambient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ambient.d.ts","sourceRoot":"","sources":["../../src/avp/ambient.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAEjE,OAAO,EAAwB,KAAK,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAKvE;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,EAAE,SAAS,MAAM,EAAwB,CAAC;AAExE,MAAM,WAAW,wBAAwB;IACvC,WAAW,EAAE,MAAM,CAAC;IACpB,0EAA0E;IAC1E,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,sDAAsD;IACtD,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAC3C,iGAAiG;IACjG,iBAAiB,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IACrC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC,CAAC;IAC/E,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;CAC1C;AAED;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,wBAAwB,GAChC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAgE3C"}
@@ -0,0 +1,127 @@
1
+ /**
2
+ * The AVP read transport (#1652).
3
+ *
4
+ * Amazon Verified Permissions speaks AWS JSON 1.0 — a POST of a JSON body with
5
+ * `x-amz-target: VerifiedPermissions.<Operation>` — so this is the same shape
6
+ * as `lexicons/aws/src/api/read-client.ts`'s Cloud Control half, pointed at a
7
+ * different service. That file is the precedent for the decision this module
8
+ * embodies: **no AWS SDK dependency**. The repo has none anywhere (the aws
9
+ * lexicon's runtime deps are `fflate` and `js-yaml`), and adding
10
+ * `@aws-sdk/client-verifiedpermissions` — 30-odd transitive packages — to the
11
+ * cedar lexicon so that one reader can issue three calls would put an AWS SDK
12
+ * in the dependency tree of a lexicon whose whole premise is that Cedar is
13
+ * vendor-neutral.
14
+ *
15
+ * ## Signing
16
+ *
17
+ * Requests are unsigned, exactly like the aws lexicon's read client. Real AWS
18
+ * rejects them; an emulator with an endpoint override does not. This is
19
+ * therefore an emulator-and-test transport today, and the honest consequence is
20
+ * encoded in {@link credentialsAvailable}: with no credentials and no endpoint
21
+ * override, the observation reports every entity NOT-OBSERVED with
22
+ * `no-credentials` rather than issuing a request that will fail. The signed
23
+ * path lands when SigV4 lands in `lexicons/aws/src/api/read-client.ts`, which
24
+ * is where it belongs — one implementation, not two.
25
+ */
26
+ /** Injectable HTTP, mirroring `AwsReadHttp` in the aws lexicon so tests avoid the network. */
27
+ export type AvpHttp = (url: string, init: {
28
+ headers: Record<string, string>;
29
+ body: string;
30
+ }, signal?: AbortSignal) => Promise<{
31
+ status: number;
32
+ text: string;
33
+ }>;
34
+ /** A failed AVP read, carrying enough to classify it without matching on prose. */
35
+ export declare class AvpReadError extends Error {
36
+ readonly status: number;
37
+ /** The service's own error code (`ResourceNotFoundException`, `AccessDeniedException`, …). */
38
+ readonly code?: string | undefined;
39
+ constructor(message: string, status: number,
40
+ /** The service's own error code (`ResourceNotFoundException`, `AccessDeniedException`, …). */
41
+ code?: string | undefined);
42
+ }
43
+ export interface AvpClientOptions {
44
+ /** Endpoint override (an emulator, or a VPC endpoint). Omit for real AWS hosts. */
45
+ endpoint?: string;
46
+ /** Region for the real-AWS host and the credential scope. */
47
+ region?: string;
48
+ http?: AvpHttp;
49
+ signal?: AbortSignal;
50
+ /** Environment to read credentials from. Defaults to `process.env`; injectable for tests. */
51
+ env?: Record<string, string | undefined>;
52
+ }
53
+ /** Service host for AVP, honouring an endpoint override. */
54
+ export declare function avpUrl(endpoint?: string, region?: string): string;
55
+ /**
56
+ * Whether this process has anything to authenticate with.
57
+ *
58
+ * An endpoint override counts: an emulator is reached without credentials, and
59
+ * refusing to look at one because `AWS_ACCESS_KEY_ID` is unset would make the
60
+ * local lanes unobservable. Everything else is the ordinary AWS credential
61
+ * surface, minus the instance-metadata path this transport cannot use anyway.
62
+ */
63
+ export declare function credentialsAvailable(env?: Record<string, string | undefined>): boolean;
64
+ /** One AVP call. Throws {@link AvpReadError} carrying the service's `__type`. */
65
+ export declare function avpCall(operation: string, payload: Record<string, unknown>, options?: AvpClientOptions): Promise<Record<string, unknown>>;
66
+ /** One policy, as `ListPolicies` reports it — no statement, only the description. */
67
+ export interface AvpPolicySummary {
68
+ policyStoreId: string;
69
+ policyId: string;
70
+ policyType: string;
71
+ /** `definition.static.description` — the channel chant's marker rides (see ./ownership.ts). */
72
+ description?: string;
73
+ createdDate?: string;
74
+ lastUpdatedDate?: string;
75
+ }
76
+ /** One policy, as `GetPolicy` reports it — the statement included. */
77
+ export interface AvpPolicyDetail extends AvpPolicySummary {
78
+ /** The Cedar policy text. */
79
+ statement: string;
80
+ }
81
+ /** `ListPolicies` for one store, paginated to exhaustion. */
82
+ export declare function listPolicies(policyStoreId: string, options?: AvpClientOptions): Promise<AvpPolicySummary[]>;
83
+ /**
84
+ * `GetPolicy` — the full record for one policy, statement included.
85
+ *
86
+ * A template-linked policy has no `definition.static`, so its statement comes
87
+ * back empty; callers treat an empty statement as "not a static policy this
88
+ * lexicon authored" rather than as a parse failure.
89
+ */
90
+ export declare function getPolicy(policyStoreId: string, policyId: string, options?: AvpClientOptions): Promise<AvpPolicyDetail>;
91
+ /** One policy store, as `GetPolicyStore` reports it. */
92
+ export interface AvpPolicyStore {
93
+ policyStoreId: string;
94
+ arn?: string;
95
+ description?: string;
96
+ createdDate?: string;
97
+ lastUpdatedDate?: string;
98
+ }
99
+ /** `GetPolicyStore` — used to resolve the store ARN the tag read needs. */
100
+ export declare function getPolicyStore(policyStoreId: string, options?: AvpClientOptions): Promise<AvpPolicyStore>;
101
+ /** `ListTagsForResource` — the store-level half of the ownership channel. */
102
+ export declare function listStoreTags(resourceArn: string, options?: AvpClientOptions): Promise<Record<string, string>>;
103
+ /** True when the failure means the store itself is not there. */
104
+ export declare function storeDoesNotExist(err: unknown): boolean;
105
+ /**
106
+ * Map a transport failure onto the closed {@link UnobservedReason} set.
107
+ *
108
+ * Anything that is not demonstrably a credential problem is `read-failed`,
109
+ * because guessing wider would let a throttle or a DNS failure masquerade as a
110
+ * verdict about the estate.
111
+ */
112
+ export declare function classifyAvpFailure(err: unknown): {
113
+ reason: "no-credentials" | "read-failed";
114
+ detail: string;
115
+ };
116
+ /**
117
+ * The address a read was issued against, for the observation's `queried` map
118
+ * (chant #1620).
119
+ *
120
+ * An absence is only as trustworthy as the address behind it, and an AVP read
121
+ * has three ways to be pointed at the wrong place: the region, the store id,
122
+ * and the `@id` annotation the policy is matched on. All three are in here.
123
+ */
124
+ export declare function policyAddress(policyStoreId: string, cedarPolicyId: string, region?: string): string;
125
+ /** The address of the store-wide enumeration itself. */
126
+ export declare function storeAddress(policyStoreId: string, region?: string): string;
127
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/avp/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * `describeResources()` against an AVP policy store (#1652).
3
+ *
4
+ * The tri-state matters more here than it does for most substrates. A Cedar
5
+ * policy that chant declares and the store does not have is a *missing
6
+ * authorization rule*: reporting it absent proposes a create, which is right.
7
+ * Reporting it absent because the store id was wrong, or because the read
8
+ * failed, proposes creating a permit that already exists — duplicating a grant.
9
+ * So every path that did not actually look says so.
10
+ *
11
+ * Built on core's observer harness (`observeEntities`), which owns the shape:
12
+ * bind-or-not-observe-all with a typed reason, bounded concurrency, a per-entity
13
+ * throw degrading to `read-failed` rather than a silent absence, and collection
14
+ * of the `queried` addresses.
15
+ */
16
+ import type { ObservationResult } from "@intentius/chant/lexicon";
17
+ import { type AvpClientOptions } from "./client.js";
18
+ export interface DescribeAvpOptions {
19
+ environment: string;
20
+ entityNames: string[];
21
+ entities: Map<string, {
22
+ entityType: string;
23
+ props: Record<string, unknown>;
24
+ }>;
25
+ /** Restrict to policies carrying chant's description marker. */
26
+ owned?: boolean;
27
+ /** Explicit store id; otherwise resolved per {@link resolvePolicyStoreId}. */
28
+ policyStoreId?: string;
29
+ client?: AvpClientOptions;
30
+ /** Environment to read the binding and credentials from. Injectable for tests. */
31
+ env?: Record<string, string | undefined>;
32
+ }
33
+ /**
34
+ * Observe the declared policy set against a live AVP store.
35
+ *
36
+ * Never throws for a transport or binding problem — a throw is the
37
+ * whole-lexicon failure and core would mark every entity `read-failed`, which
38
+ * is a worse-shaped version of what this returns directly with the right
39
+ * reason on it.
40
+ */
41
+ export declare function describeAvpResources(options: DescribeAvpOptions): Promise<ObservationResult>;
42
+ //# sourceMappingURL=describe-resources.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"describe-resources.d.ts","sourceRoot":"","sources":["../../src/avp/describe-resources.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAoB,MAAM,0BAA0B,CAAC;AAWpF,OAAO,EAML,KAAK,gBAAgB,EACtB,MAAM,UAAU,CAAC;AASlB,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC,CAAC;IAC9E,gEAAgE;IAChE,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,8EAA8E;IAC9E,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,kFAAkF;IAClF,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;CAC1C;AAyCD;;;;;;;GAOG;AACH,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CA+GlG"}
@@ -0,0 +1,120 @@
1
+ /**
2
+ * Typed embedding of a cedar policy into `AWS::VerifiedPermissions::Policy`
3
+ * (#1652).
4
+ *
5
+ * The aws lexicon keeps the deployment vehicle — its generated
6
+ * `VerifiedPermissionsPolicy` takes a required `PolicyStoreId` and a required
7
+ * `Definition`, and the `Definition.Static.Statement` inside it is an opaque
8
+ * string. Opaque is the problem the whole cedar lexicon exists to remove: today
9
+ * a team writes that string with `${}` templating and finds out at deploy time
10
+ * whether the entity type exists.
11
+ *
12
+ * This module closes the loop without joining the two lexicons together. It
13
+ * emits the *string* and the *JSON envelope* AVP expects and stops there:
14
+ * nothing here imports `@intentius/chant-lexicon-aws`, and nothing here needs
15
+ * to. A project that has both installed writes
16
+ *
17
+ * ```ts
18
+ * new VerifiedPermissionsPolicy({
19
+ * PolicyStoreId: store.ref(),
20
+ * Definition: avpPolicyDefinition("ownerRead", ownerReadProps),
21
+ * });
22
+ * ```
23
+ *
24
+ * and the statement is the same text `chant build` writes to `.cedar`, rendered
25
+ * by the same renderer, with `@id` intact.
26
+ *
27
+ * ### Why no dependency, and why the example uses plain objects
28
+ *
29
+ * A cedar → aws dependency would invert the epic's decision that Cedar is
30
+ * vendor-neutral and AVP is one of several evaluators, and it would make the
31
+ * cedar lexicon unbuildable without the aws one. The seam is therefore the
32
+ * data shape, which is stable CloudFormation, and
33
+ * `examples/avp-embedding/` demonstrates the pairing with a plain-object stand-in
34
+ * for `VerifiedPermissionsPolicy` — the shipped examples build with the cedar
35
+ * serializer alone, so a real cross-lexicon example could not run in this
36
+ * repo's example harness at all. The stand-in carries the exact prop names the
37
+ * generated class declares (`PolicyStoreId`, `Definition`, `Name`), so the
38
+ * substitution is a one-line edit in a real project.
39
+ */
40
+ import type { Declarable } from "@intentius/chant/declarable";
41
+ import type { OwnershipMarker } from "@intentius/chant/ownership";
42
+ import { type CedarPolicyProps } from "../serializer.js";
43
+ import { type PolicyJson } from "../spec/wasm.js";
44
+ /** `Definition.Static` — the static-policy half of the AVP definition union. */
45
+ export interface AvpStaticDefinition {
46
+ Statement: string;
47
+ Description?: string;
48
+ }
49
+ /** The `Definition` property of `AWS::VerifiedPermissions::Policy`. */
50
+ export interface AvpPolicyDefinition {
51
+ Static: AvpStaticDefinition;
52
+ }
53
+ /** The props of `AWS::VerifiedPermissions::Policy` this module can fill. */
54
+ export interface AvpPolicyResource {
55
+ PolicyStoreId: string;
56
+ Definition: AvpPolicyDefinition;
57
+ }
58
+ export interface AvpEmbedOptions {
59
+ /**
60
+ * Ownership marker to stamp into the description — the per-policy channel
61
+ * (see ./ownership.ts). Supply it and `describeResources`/`exportResources`
62
+ * can tell this policy from one somebody added in the console.
63
+ */
64
+ ownership?: OwnershipMarker;
65
+ /** The author's own description, kept ahead of the marker. */
66
+ description?: string;
67
+ /** Override the Cedar id. Defaults to the serializer's own derivation. */
68
+ policyId?: string;
69
+ }
70
+ /**
71
+ * The Cedar policy text for one policy — the exact string
72
+ * `Definition.Static.Statement` wants.
73
+ *
74
+ * `name` is the chant entity name; the `@id` annotation the statement carries
75
+ * is derived from it the same way the serializer derives it, which is what lets
76
+ * the live observation match a policy in the store back to the entity that
77
+ * declared it.
78
+ */
79
+ export declare function avpStatement(name: string, props: CedarPolicyProps | Record<string, unknown>, options?: AvpEmbedOptions): string;
80
+ /**
81
+ * The Cedar JSON policy format for one policy — for an evaluator that takes
82
+ * JSON rather than text (`cedar-agent`, an embedded `cedar-wasm`).
83
+ *
84
+ * Not what AVP's `Definition` wants; AVP takes the text. Emitted here so the
85
+ * seam is documented in both directions rather than only the AWS one.
86
+ *
87
+ * Built the way the serializer's JSON leg is built (#1653): render the text,
88
+ * then hand it to `cedar-wasm`, so what comes back is Cedar's own reading
89
+ * rather than a second, worse encoder. Throws on text Cedar refuses — this is
90
+ * an authoring-time call, and a policy the module cannot read is a defect the
91
+ * caller wants to hear about rather than a `undefined` to thread through.
92
+ */
93
+ export declare function avpStatementJSON(name: string, props: CedarPolicyProps | Record<string, unknown>, options?: AvpEmbedOptions): PolicyJson;
94
+ /**
95
+ * The `Definition` property of `AWS::VerifiedPermissions::Policy`.
96
+ *
97
+ * With `options.ownership` set, the description carries chant's marker — the
98
+ * only per-policy ownership channel AVP has, because policies are not taggable.
99
+ */
100
+ export declare function avpPolicyDefinition(name: string, props: CedarPolicyProps | Record<string, unknown>, options?: AvpEmbedOptions): AvpPolicyDefinition;
101
+ /**
102
+ * Both required props of `AWS::VerifiedPermissions::Policy`, ready to spread
103
+ * into the generated class.
104
+ *
105
+ * `PolicyStoreId` is a string here rather than an AttrRef because this module
106
+ * does not know the aws lexicon's reference types. A project passes
107
+ * `store.ref()` in place of the literal and TypeScript is satisfied by the
108
+ * generated class's own prop type, not by this one.
109
+ */
110
+ export declare function avpPolicyResource(name: string, props: CedarPolicyProps | Record<string, unknown>, policyStoreId: string, options?: AvpEmbedOptions): AvpPolicyResource;
111
+ /**
112
+ * Every `Cedar::Policy` in a build, rendered as AVP definitions and keyed by
113
+ * chant entity name.
114
+ *
115
+ * The whole-set form: one call turns a policy set into the definitions a stack
116
+ * of `VerifiedPermissionsPolicy` declarations needs, with references between
117
+ * declared entities already walked (that is what `cedarPolicyRecords` does).
118
+ */
119
+ export declare function avpPolicySet(entities: Map<string, Declarable>, options?: AvpEmbedOptions): Record<string, AvpPolicyDefinition>;
120
+ //# sourceMappingURL=embed.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"embed.d.ts","sourceRoot":"","sources":["../../src/avp/embed.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,EAIL,KAAK,gBAAgB,EACtB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAgB,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAG7D,gFAAgF;AAChF,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,uEAAuE;AACvE,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,mBAAmB,CAAC;CAC7B;AAED,4EAA4E;AAC5E,MAAM,WAAW,iBAAiB;IAChC,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,mBAAmB,CAAC;CACjC;AAED,MAAM,WAAW,eAAe;IAC9B;;;;OAIG;IACH,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,8DAA8D;IAC9D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAMD;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjD,OAAO,GAAE,eAAoB,GAC5B,MAAM,CAGR;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjD,OAAO,GAAE,eAAoB,GAC5B,UAAU,CAOZ;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjD,OAAO,GAAE,eAAoB,GAC5B,mBAAmB,CAarB;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjD,aAAa,EAAE,MAAM,EACrB,OAAO,GAAE,eAAoB,GAC5B,iBAAiB,CAEnB;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,EACjC,OAAO,GAAE,eAAoB,GAC5B,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAMrC"}
@@ -0,0 +1,94 @@
1
+ /**
2
+ * `exportResources()` against an AVP policy store (#1652).
3
+ *
4
+ * `describeResources` returns scrubbed metadata for diffing — you cannot
5
+ * regenerate a policy from "STATIC, last updated Tuesday". This is the other
6
+ * half: the live statement, parsed back into the props a `Cedar::Policy`
7
+ * declaration carries, as `TemplateIR` so it feeds `templateGenerator()`
8
+ * unchanged. The scrubbing boundary stays single-purpose; nothing here is
9
+ * reachable from the lifecycle paths, which consume the lexicon through
10
+ * `ObservationLexicon` and cannot see this method at all.
11
+ *
12
+ * ## The parse is the import parser's
13
+ *
14
+ * The live-export guide's third step is "map to `TemplateIR` by reusing your
15
+ * import parser", and #1653 shipped one. So a live statement goes through
16
+ * `CedarTemplateParser` — the same code path `chant import policies.cedar`
17
+ * takes — rather than a second reader that would have to re-derive scope
18
+ * mapping, clause-text recovery and template detection, and would drift the
19
+ * first time either side changed. This module's job is the AVP half: bind the
20
+ * store, enumerate it, decide what is server-written, and apply the filters.
21
+ *
22
+ * ## What is server-written here
23
+ *
24
+ * The live-export guide says strip to the declared shape by default and keep
25
+ * the rest under `verbatim`. For AVP the split is unusually clean, because the
26
+ * only thing a user authors is the statement. Everything else on the record —
27
+ * `policyId` (service-assigned), `policyStoreId`, `policyType`, `createdDate`,
28
+ * `lastUpdatedDate`, and the derived `principal`/`resource` summaries AVP
29
+ * computes from the statement — is server-written and stripped by default.
30
+ * `Description` is stripped too: chant's marker lives in it, so exporting it
31
+ * verbatim into regenerated source would bake one environment's ownership stamp
32
+ * into the code that produces every environment.
33
+ *
34
+ * `verbatim: true` puts all of it back under an `avp` key, raw description
35
+ * included.
36
+ */
37
+ import type { ExportedTemplate, ResourceSelector } from "@intentius/chant/lexicon";
38
+ import type { ResourceIR } from "@intentius/chant/import/parser";
39
+ import { type AvpClientOptions } from "./client.js";
40
+ import { type AvpLivePolicy } from "./store.js";
41
+ export interface ExportAvpOptions {
42
+ environment: string;
43
+ selector?: ResourceSelector;
44
+ /** Restrict to policies carrying chant's description marker. */
45
+ owned?: boolean;
46
+ /** Keep the server-written AVP record alongside the authored props. */
47
+ verbatim?: boolean;
48
+ policyStoreId?: string;
49
+ entities?: Map<string, {
50
+ entityType: string;
51
+ props: Record<string, unknown>;
52
+ }>;
53
+ client?: AvpClientOptions;
54
+ env?: Record<string, string | undefined>;
55
+ }
56
+ /** The server-written AVP record, kept only under `verbatim`. */
57
+ export interface AvpRecord {
58
+ policyId: string;
59
+ policyStoreId: string;
60
+ policyType: string;
61
+ description?: string;
62
+ createdDate?: string;
63
+ lastUpdatedDate?: string;
64
+ statement: string;
65
+ }
66
+ /**
67
+ * One live policy as import IR, or `undefined` when its statement could not be
68
+ * read or parsed.
69
+ *
70
+ * The parse is `CedarTemplateParser`'s — one policy is a policy set of one, so
71
+ * the same reader `chant import` uses answers here, including whether Cedar
72
+ * read it as a static policy or as a template (`Cedar::Policy` vs
73
+ * `Cedar::Template`, decided by whether it carries a slot). The `logicalId` it
74
+ * assigns is the Cedar policy id; turning that into a TypeScript identifier is
75
+ * `CedarGenerator`'s job downstream, and doing it here too would apply the
76
+ * transform twice.
77
+ *
78
+ * Dropping an unparseable policy is deliberate. A regenerated policy set that
79
+ * silently lost a `forbid` reads as a working export and is an authorization
80
+ * hole; a missing entry is visible.
81
+ */
82
+ export declare function policyToResourceIR(policy: AvpLivePolicy, options?: {
83
+ verbatim?: boolean;
84
+ }): ResourceIR | undefined;
85
+ /**
86
+ * Read a live policy store as full-fidelity import IR.
87
+ *
88
+ * Unlike the observation, this throws when it cannot read: `chant import` has
89
+ * no tri-state to degrade into, and an empty template returned from a failed
90
+ * read would generate a source tree that deletes every policy. The one
91
+ * exception is a store that does not exist, which is an honest empty estate.
92
+ */
93
+ export declare function exportAvpResources(options: ExportAvpOptions): Promise<ExportedTemplate>;
94
+ //# sourceMappingURL=live-export.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"live-export.d.ts","sourceRoot":"","sources":["../../src/avp/live-export.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACnF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAEjE,OAAO,EAA2C,KAAK,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAE1F,OAAO,EAA0C,KAAK,aAAa,EAAE,MAAM,SAAS,CAAC;AAErF,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,gEAAgE;IAChE,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,uEAAuE;IACvE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC,CAAC;IAC/E,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;CAC1C;AAED,iEAAiE;AACjE,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,aAAa,EACrB,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAO,GACnC,UAAU,GAAG,SAAS,CAgCxB;AAED;;;;;;;GAOG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAuD7F"}