@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.
- package/README.md +190 -0
- package/dist/avp/ambient.d.ts +54 -0
- package/dist/avp/ambient.d.ts.map +1 -0
- package/dist/avp/client.d.ts +127 -0
- package/dist/avp/client.d.ts.map +1 -0
- package/dist/avp/describe-resources.d.ts +42 -0
- package/dist/avp/describe-resources.d.ts.map +1 -0
- package/dist/avp/embed.d.ts +120 -0
- package/dist/avp/embed.d.ts.map +1 -0
- package/dist/avp/live-export.d.ts +94 -0
- package/dist/avp/live-export.d.ts.map +1 -0
- package/dist/avp/ownership.d.ts +97 -0
- package/dist/avp/ownership.d.ts.map +1 -0
- package/dist/avp/statement.d.ts +22 -0
- package/dist/avp/statement.d.ts.map +1 -0
- package/dist/avp/store.d.ts +82 -0
- package/dist/avp/store.d.ts.map +1 -0
- package/dist/avp/testdata/mock-transport.d.ts +55 -0
- package/dist/avp/testdata/mock-transport.d.ts.map +1 -0
- package/dist/codegen/docs-cli.d.ts +3 -0
- package/dist/codegen/docs-cli.d.ts.map +1 -0
- package/dist/codegen/docs.d.ts +26 -0
- package/dist/codegen/docs.d.ts.map +1 -0
- package/dist/codegen/emit.d.ts +85 -0
- package/dist/codegen/emit.d.ts.map +1 -0
- package/dist/codegen/generate-cli.d.ts +3 -0
- package/dist/codegen/generate-cli.d.ts.map +1 -0
- package/dist/codegen/generate.d.ts +37 -0
- package/dist/codegen/generate.d.ts.map +1 -0
- package/dist/codegen/naming.d.ts +48 -0
- package/dist/codegen/naming.d.ts.map +1 -0
- package/dist/codegen/package.d.ts +10 -0
- package/dist/codegen/package.d.ts.map +1 -0
- package/dist/composites/deny-by-default-set.d.ts +58 -0
- package/dist/composites/deny-by-default-set.d.ts.map +1 -0
- package/dist/composites/index.d.ts +12 -0
- package/dist/composites/index.d.ts.map +1 -0
- package/dist/composites/owner-can-manage.d.ts +48 -0
- package/dist/composites/owner-can-manage.d.ts.map +1 -0
- package/dist/config.d.ts +102 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/coverage.d.ts +59 -0
- package/dist/coverage.d.ts.map +1 -0
- package/dist/detect.d.ts +18 -0
- package/dist/detect.d.ts.map +1 -0
- package/dist/generated/index.d.ts +251 -0
- package/dist/generated/index.d.ts.map +1 -0
- package/dist/generated/runtime.d.ts +2 -0
- package/dist/generated/runtime.d.ts.map +1 -0
- package/dist/import/adapter.d.ts +21 -0
- package/dist/import/adapter.d.ts.map +1 -0
- package/dist/import/clause-text.d.ts +38 -0
- package/dist/import/clause-text.d.ts.map +1 -0
- package/dist/import/generator.d.ts +53 -0
- package/dist/import/generator.d.ts.map +1 -0
- package/dist/import/parser.d.ts +57 -0
- package/dist/import/parser.d.ts.map +1 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/init-templates.d.ts +32 -0
- package/dist/init-templates.d.ts.map +1 -0
- package/dist/integrity.json +22 -0
- package/dist/lint/audit-catalog.d.ts +29 -0
- package/dist/lint/audit-catalog.d.ts.map +1 -0
- package/dist/lint/post-synth/cedar-helpers.d.ts +97 -0
- package/dist/lint/post-synth/cedar-helpers.d.ts.map +1 -0
- package/dist/lint/post-synth/cedc010.d.ts +17 -0
- package/dist/lint/post-synth/cedc010.d.ts.map +1 -0
- package/dist/lint/post-synth/cedc011.d.ts +17 -0
- package/dist/lint/post-synth/cedc011.d.ts.map +1 -0
- package/dist/lint/post-synth/cedc012.d.ts +21 -0
- package/dist/lint/post-synth/cedc012.d.ts.map +1 -0
- package/dist/lint/post-synth/cedc013.d.ts +20 -0
- package/dist/lint/post-synth/cedc013.d.ts.map +1 -0
- package/dist/lint/post-synth/cedc014.d.ts +19 -0
- package/dist/lint/post-synth/cedc014.d.ts.map +1 -0
- package/dist/lint/post-synth/cede010.d.ts +34 -0
- package/dist/lint/post-synth/cede010.d.ts.map +1 -0
- package/dist/lint/post-synth/cede011.d.ts +22 -0
- package/dist/lint/post-synth/cede011.d.ts.map +1 -0
- package/dist/lint/post-synth/ceds010.d.ts +24 -0
- package/dist/lint/post-synth/ceds010.d.ts.map +1 -0
- package/dist/lint/post-synth/ceds011.d.ts +19 -0
- package/dist/lint/post-synth/ceds011.d.ts.map +1 -0
- package/dist/lint/post-synth/ceds012.d.ts +17 -0
- package/dist/lint/post-synth/ceds012.d.ts.map +1 -0
- package/dist/lint/post-synth/index.d.ts +3 -0
- package/dist/lint/post-synth/index.d.ts.map +1 -0
- package/dist/lint/post-synth/wasm-helpers.d.ts +108 -0
- package/dist/lint/post-synth/wasm-helpers.d.ts.map +1 -0
- package/dist/lint/rules/index.d.ts +10 -0
- package/dist/lint/rules/index.d.ts.map +1 -0
- package/dist/lint/rules/policy-shape.d.ts +31 -0
- package/dist/lint/rules/policy-shape.d.ts.map +1 -0
- package/dist/lsp/completions.d.ts +24 -0
- package/dist/lsp/completions.d.ts.map +1 -0
- package/dist/lsp/hover.d.ts +11 -0
- package/dist/lsp/hover.d.ts.map +1 -0
- package/dist/lsp/registry.d.ts +45 -0
- package/dist/lsp/registry.d.ts.map +1 -0
- package/dist/manifest.json +8 -0
- package/dist/mcp/index.d.ts +34 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/policy-coverage.d.ts +81 -0
- package/dist/mcp/policy-coverage.d.ts.map +1 -0
- package/dist/meta.json +699 -0
- package/dist/okf/index.md +37 -0
- package/dist/okf/rules/CEDC001.md +11 -0
- package/dist/okf/rules/CEDC010.md +11 -0
- package/dist/okf/rules/CEDC011.md +15 -0
- package/dist/okf/rules/CEDC012.md +11 -0
- package/dist/okf/rules/CEDC013.md +15 -0
- package/dist/okf/rules/CEDC014.md +15 -0
- package/dist/okf/rules/CEDE010.md +15 -0
- package/dist/okf/rules/CEDE011.md +15 -0
- package/dist/okf/rules/CEDS010.md +15 -0
- package/dist/okf/rules/CEDS011.md +11 -0
- package/dist/okf/rules/CEDS012.md +15 -0
- package/dist/okf/types/AdminAction.md +14 -0
- package/dist/okf/types/Application.md +14 -0
- package/dist/okf/types/ApproveAction.md +13 -0
- package/dist/okf/types/CommentAction.md +14 -0
- package/dist/okf/types/CreateAction.md +14 -0
- package/dist/okf/types/DeleteAction.md +14 -0
- package/dist/okf/types/Document.md +18 -0
- package/dist/okf/types/Folder.md +15 -0
- package/dist/okf/types/Group.md +14 -0
- package/dist/okf/types/ListAction.md +14 -0
- package/dist/okf/types/Policy.md +29 -0
- package/dist/okf/types/ReadAction.md +14 -0
- package/dist/okf/types/ServiceAccount.md +15 -0
- package/dist/okf/types/ShareAction.md +14 -0
- package/dist/okf/types/Team.md +14 -0
- package/dist/okf/types/User.md +18 -0
- package/dist/okf/types/WriteAction.md +14 -0
- package/dist/package-cli.d.ts +3 -0
- package/dist/package-cli.d.ts.map +1 -0
- package/dist/plugin.d.ts +8 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/rules/cedar-helpers.ts +209 -0
- package/dist/rules/cedc010.ts +80 -0
- package/dist/rules/cedc011.ts +47 -0
- package/dist/rules/cedc012.ts +64 -0
- package/dist/rules/cedc013.ts +68 -0
- package/dist/rules/cedc014.ts +73 -0
- package/dist/rules/cede010.ts +89 -0
- package/dist/rules/cede011.ts +58 -0
- package/dist/rules/ceds010.ts +57 -0
- package/dist/rules/ceds011.ts +42 -0
- package/dist/rules/ceds012.ts +50 -0
- package/dist/rules/policy-shape.ts +148 -0
- package/dist/rules/wasm-helpers.ts +315 -0
- package/dist/serializer.d.ts +138 -0
- package/dist/serializer.d.ts.map +1 -0
- package/dist/spec/fetch.d.ts +71 -0
- package/dist/spec/fetch.d.ts.map +1 -0
- package/dist/spec/parse.d.ts +113 -0
- package/dist/spec/parse.d.ts.map +1 -0
- package/dist/spec/pin.d.ts +116 -0
- package/dist/spec/pin.d.ts.map +1 -0
- package/dist/spec/pinned-names.json +18 -0
- package/dist/spec/wasm.d.ts +143 -0
- package/dist/spec/wasm.d.ts.map +1 -0
- package/dist/types/index.d.ts +219 -0
- package/dist/validate-cli.d.ts +3 -0
- package/dist/validate-cli.d.ts.map +1 -0
- package/dist/validate.d.ts +25 -0
- package/dist/validate.d.ts.map +1 -0
- package/package.json +75 -0
- package/src/avp/OWNERSHIP.md +125 -0
- package/src/avp/ambient.test.ts +113 -0
- package/src/avp/ambient.ts +124 -0
- package/src/avp/client.ts +310 -0
- package/src/avp/describe-resources.test.ts +316 -0
- package/src/avp/describe-resources.ts +215 -0
- package/src/avp/embed.test.ts +114 -0
- package/src/avp/embed.ts +190 -0
- package/src/avp/live-export.test.ts +232 -0
- package/src/avp/live-export.ts +185 -0
- package/src/avp/ownership.test.ts +101 -0
- package/src/avp/ownership.ts +170 -0
- package/src/avp/statement.ts +50 -0
- package/src/avp/store.ts +152 -0
- package/src/avp/testdata/mock-transport.ts +147 -0
- package/src/codegen/docs-cli.ts +7 -0
- package/src/codegen/docs.ts +873 -0
- package/src/codegen/emit.ts +496 -0
- package/src/codegen/generate-cli.ts +18 -0
- package/src/codegen/generate.test.ts +128 -0
- package/src/codegen/generate.ts +123 -0
- package/src/codegen/naming.ts +101 -0
- package/src/codegen/package.ts +52 -0
- package/src/composites/composites.test.ts +206 -0
- package/src/composites/deny-by-default-set.ts +98 -0
- package/src/composites/index.ts +13 -0
- package/src/composites/owner-can-manage.ts +80 -0
- package/src/config-namespace.test.ts +44 -0
- package/src/config.test.ts +82 -0
- package/src/config.ts +119 -0
- package/src/coverage.test.ts +61 -0
- package/src/coverage.ts +166 -0
- package/src/detect.test.ts +64 -0
- package/src/detect.ts +59 -0
- package/src/generated/index.d.ts +219 -0
- package/src/generated/index.ts +279 -0
- package/src/generated/lexicon-cedar.json +699 -0
- package/src/generated/runtime.ts +2 -0
- package/src/import/adapter.ts +63 -0
- package/src/import/clause-text.ts +178 -0
- package/src/import/generator.test.ts +133 -0
- package/src/import/generator.ts +219 -0
- package/src/import/parser.test.ts +265 -0
- package/src/import/parser.ts +352 -0
- package/src/import/roundtrip.test.ts +127 -0
- package/src/import/testdata/full.cedar +36 -0
- package/src/import/testdata/full.cedar.json +238 -0
- package/src/import/testdata/realistic.cedar +35 -0
- package/src/import/testdata/simple.cedar +6 -0
- package/src/index.ts +94 -0
- package/src/init-templates.test.ts +158 -0
- package/src/init-templates.ts +358 -0
- package/src/lint/audit-catalog.ts +130 -0
- package/src/lint/post-synth/cedar-helpers.ts +209 -0
- package/src/lint/post-synth/cedc010.ts +80 -0
- package/src/lint/post-synth/cedc011.ts +47 -0
- package/src/lint/post-synth/cedc012.ts +64 -0
- package/src/lint/post-synth/cedc013.ts +68 -0
- package/src/lint/post-synth/cedc014.ts +73 -0
- package/src/lint/post-synth/cede010.ts +89 -0
- package/src/lint/post-synth/cede011.ts +58 -0
- package/src/lint/post-synth/ceds010.ts +57 -0
- package/src/lint/post-synth/ceds011.ts +42 -0
- package/src/lint/post-synth/ceds012.ts +50 -0
- package/src/lint/post-synth/index.ts +25 -0
- package/src/lint/post-synth/post-synth.test.ts +474 -0
- package/src/lint/post-synth/wasm-helpers.ts +315 -0
- package/src/lint/rules/index.ts +12 -0
- package/src/lint/rules/policy-shape.test.ts +90 -0
- package/src/lint/rules/policy-shape.ts +148 -0
- package/src/lsp/completions.test.ts +111 -0
- package/src/lsp/completions.ts +55 -0
- package/src/lsp/hover.test.ts +82 -0
- package/src/lsp/hover.ts +75 -0
- package/src/lsp/registry.ts +74 -0
- package/src/mcp/index.ts +103 -0
- package/src/mcp/policy-coverage.test.ts +176 -0
- package/src/mcp/policy-coverage.ts +205 -0
- package/src/package-cli.ts +22 -0
- package/src/plugin.test.ts +115 -0
- package/src/plugin.ts +312 -0
- package/src/serializer.test.ts +502 -0
- package/src/serializer.ts +335 -0
- package/src/skills/chant-cedar-authoring.md +180 -0
- package/src/skills/chant-cedar-avp-embedding.md +125 -0
- package/src/skills/chant-cedar-meta-policy.md +119 -0
- package/src/spec/default-schema.cedarschema +108 -0
- package/src/spec/fetch.ts +107 -0
- package/src/spec/parse.test.ts +123 -0
- package/src/spec/parse.ts +253 -0
- package/src/spec/pin.test.ts +88 -0
- package/src/spec/pin.ts +243 -0
- package/src/spec/pinned-names.json +18 -0
- package/src/spec/wasm.ts +283 -0
- package/src/validate-cli.ts +8 -0
- package/src/validate.ts +85 -0
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The epic's round-trip: TypeScript → `.cedar` → parse → TypeScript → `.cedar`,
|
|
3
|
+
* with the two `.cedar` outputs byte-identical.
|
|
4
|
+
*
|
|
5
|
+
* The regenerated TypeScript is checked as source, and the second serialization
|
|
6
|
+
* is driven from the same IR the generator emitted from — running the emitted
|
|
7
|
+
* file would need a compiler in the loop to prove something the IR already
|
|
8
|
+
* decides. `generator.test.ts` covers what that source says.
|
|
9
|
+
*
|
|
10
|
+
* Two normalizations are real and are asserted here rather than hidden:
|
|
11
|
+
*
|
|
12
|
+
* - **Annotation order.** Annotations serialize into a sorted map, so authored
|
|
13
|
+
* order is not recoverable (#1648 §1). `@id` is always emitted first, and the
|
|
14
|
+
* rest come back alphabetically.
|
|
15
|
+
* - **Clause order.** `when`/`unless` are separate props, so an interleaved
|
|
16
|
+
* `when … unless … when` regroups into all `when`s and then all `unless`es.
|
|
17
|
+
*
|
|
18
|
+
* Both settle after one pass, which is what the idempotence test pins.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
import { describe, test, expect } from "vitest";
|
|
22
|
+
import { readFileSync } from "fs";
|
|
23
|
+
import { join } from "path";
|
|
24
|
+
import { DECLARABLE_MARKER, type Declarable } from "@intentius/chant/declarable";
|
|
25
|
+
import type { SerializerResult } from "@intentius/chant/serializer";
|
|
26
|
+
import { checkParsePolicySet } from "@cedar-policy/cedar-wasm/nodejs";
|
|
27
|
+
import { cedarSerializer, CEDAR_JSON_FILENAME, CEDAR_POLICY_TYPE } from "../serializer";
|
|
28
|
+
import { CedarParser, type CedarPolicyIR } from "./parser";
|
|
29
|
+
import { CedarGenerator, loadActionConstants, sanitizeName } from "./generator";
|
|
30
|
+
|
|
31
|
+
const testdata = (file: string) => readFileSync(join(import.meta.dirname, "testdata", file), "utf8");
|
|
32
|
+
|
|
33
|
+
/** The declarables an authored `policies.ts` would have produced. */
|
|
34
|
+
function declarablesOf(entities: CedarPolicyIR[]): Map<string, Declarable> {
|
|
35
|
+
const map = new Map<string, Declarable>();
|
|
36
|
+
for (const entity of entities) {
|
|
37
|
+
map.set(sanitizeName(entity.name), {
|
|
38
|
+
[DECLARABLE_MARKER]: true,
|
|
39
|
+
lexicon: "cedar",
|
|
40
|
+
entityType: CEDAR_POLICY_TYPE,
|
|
41
|
+
kind: "resource",
|
|
42
|
+
props: entity.props,
|
|
43
|
+
} as unknown as Declarable);
|
|
44
|
+
}
|
|
45
|
+
return map;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function serialize(entities: CedarPolicyIR[]): SerializerResult {
|
|
49
|
+
const out = cedarSerializer.serialize(declarablesOf(entities));
|
|
50
|
+
if (typeof out === "string") throw new Error(`expected a SerializerResult, got ${JSON.stringify(out)}`);
|
|
51
|
+
return out;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** One full lap: text in, IR, regenerated TypeScript, text back out. */
|
|
55
|
+
function lap(text: string): { entities: CedarPolicyIR[]; source: string; text: string } {
|
|
56
|
+
const { entities } = new CedarParser().parse(text);
|
|
57
|
+
const source = new CedarGenerator({ actionConstants: loadActionConstants() }).generate(entities).source;
|
|
58
|
+
return { entities, source, text: serialize(entities).primary };
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// ── 1–3. The fixtures ──────────────────────────────────────────────
|
|
62
|
+
|
|
63
|
+
describe("round-trip", () => {
|
|
64
|
+
for (const fixture of ["simple", "realistic", "full"]) {
|
|
65
|
+
test(`${fixture}.cedar → IR → TypeScript → .cedar is byte-identical`, () => {
|
|
66
|
+
const original = testdata(`${fixture}.cedar`);
|
|
67
|
+
const round = lap(original);
|
|
68
|
+
|
|
69
|
+
expect(round.text).toBe(original);
|
|
70
|
+
expect(round.source).toContain("new Policy(");
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
test("4. a second lap changes nothing — the normalizations settle after one", () => {
|
|
75
|
+
const first = lap(testdata("full.cedar"));
|
|
76
|
+
const second = lap(first.text);
|
|
77
|
+
|
|
78
|
+
expect(second.text).toBe(first.text);
|
|
79
|
+
expect(second.source).toBe(first.source);
|
|
80
|
+
expect(second.entities).toEqual(first.entities);
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
// ── The JSON leg on both sides ─────────────────────────────────────
|
|
85
|
+
|
|
86
|
+
describe("the JSON leg", () => {
|
|
87
|
+
test("survives the lap and stays a policy set Cedar accepts", () => {
|
|
88
|
+
const original = testdata("full.cedar");
|
|
89
|
+
const round = lap(original);
|
|
90
|
+
|
|
91
|
+
const before = JSON.parse(serialize(new CedarParser().parse(original).entities).files![CEDAR_JSON_FILENAME]);
|
|
92
|
+
const after = JSON.parse(serialize(round.entities).files![CEDAR_JSON_FILENAME]);
|
|
93
|
+
|
|
94
|
+
expect(after).toEqual(before);
|
|
95
|
+
expect(checkParsePolicySet(after).type).toBe("success");
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
test("importing the JSON envelope reaches the same policies as importing the text", () => {
|
|
99
|
+
const fromText = new CedarParser().parse(testdata("full.cedar")).entities;
|
|
100
|
+
const fromJSON = new CedarParser().parse(testdata("full.cedar.json")).entities;
|
|
101
|
+
|
|
102
|
+
// Scopes, effects, annotations and clause *count* match exactly; the clause
|
|
103
|
+
// text differs by the module's parenthesization, which is why the text leg
|
|
104
|
+
// is the one that round-trips byte-for-byte.
|
|
105
|
+
const shapeOf = (entities: CedarPolicyIR[]) =>
|
|
106
|
+
entities.map((e) => ({
|
|
107
|
+
kind: e.kind,
|
|
108
|
+
name: e.name,
|
|
109
|
+
...e.props,
|
|
110
|
+
when: (e.props.when as string[] | undefined)?.length ?? 0,
|
|
111
|
+
unless: (e.props.unless as string[] | undefined)?.length ?? 0,
|
|
112
|
+
}));
|
|
113
|
+
|
|
114
|
+
expect(shapeOf(fromJSON)).toEqual(shapeOf(fromText));
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
test("a JSON-envelope import still serializes to a policy set Cedar accepts", () => {
|
|
118
|
+
const { entities } = new CedarParser().parse(testdata("full.cedar.json"));
|
|
119
|
+
const result = serialize(entities);
|
|
120
|
+
|
|
121
|
+
// The JSON companion is built from the emitted text, so it parsing is the
|
|
122
|
+
// text parsing. `{ staticPolicies: <text> }` would not do here: the
|
|
123
|
+
// document contains a template, and that channel only takes static policies.
|
|
124
|
+
expect(checkParsePolicySet(JSON.parse(result.files![CEDAR_JSON_FILENAME])).type).toBe("success");
|
|
125
|
+
expect(result.warnings ?? []).toEqual([]);
|
|
126
|
+
});
|
|
127
|
+
});
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
@id("full-grant")
|
|
2
|
+
@doc("Everything the authoring model can carry, in one policy.")
|
|
3
|
+
@owner("platform")
|
|
4
|
+
@ticket("SEC-12")
|
|
5
|
+
permit (
|
|
6
|
+
principal is App::User in App::Group::"engineering",
|
|
7
|
+
action in [App::Action::"read", App::Action::"write", App::Action::"list"],
|
|
8
|
+
resource is App::Document in App::Folder::"handbook"
|
|
9
|
+
)
|
|
10
|
+
when { resource.owner == principal && context.mfa == true }
|
|
11
|
+
when { principal.department == "eng" }
|
|
12
|
+
unless { resource.classification == "secret" }
|
|
13
|
+
unless { context.ip.isInRange(ip("10.0.0.0/8")) };
|
|
14
|
+
|
|
15
|
+
@id("deny-anonymous")
|
|
16
|
+
forbid (
|
|
17
|
+
principal,
|
|
18
|
+
action,
|
|
19
|
+
resource
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
@id("quoted-note")
|
|
23
|
+
@note("say \"hi\" \\ done")
|
|
24
|
+
permit (
|
|
25
|
+
principal == App::ServiceAccount::"ci",
|
|
26
|
+
action in [App::Action::"create", App::Action::"approve"],
|
|
27
|
+
resource
|
|
28
|
+
)
|
|
29
|
+
when { context.note == "a } b { c" };
|
|
30
|
+
|
|
31
|
+
@id("share-with-slots")
|
|
32
|
+
permit (
|
|
33
|
+
principal == ?principal,
|
|
34
|
+
action == App::Action::"share",
|
|
35
|
+
resource in ?resource
|
|
36
|
+
);
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
{
|
|
2
|
+
"staticPolicies": {
|
|
3
|
+
"full-grant": {
|
|
4
|
+
"effect": "permit",
|
|
5
|
+
"principal": {
|
|
6
|
+
"op": "is",
|
|
7
|
+
"entity_type": "App::User",
|
|
8
|
+
"in": {
|
|
9
|
+
"entity": {
|
|
10
|
+
"type": "App::Group",
|
|
11
|
+
"id": "engineering"
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"action": {
|
|
16
|
+
"op": "in",
|
|
17
|
+
"entities": [
|
|
18
|
+
{
|
|
19
|
+
"type": "App::Action",
|
|
20
|
+
"id": "read"
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"type": "App::Action",
|
|
24
|
+
"id": "write"
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"type": "App::Action",
|
|
28
|
+
"id": "list"
|
|
29
|
+
}
|
|
30
|
+
]
|
|
31
|
+
},
|
|
32
|
+
"resource": {
|
|
33
|
+
"op": "is",
|
|
34
|
+
"entity_type": "App::Document",
|
|
35
|
+
"in": {
|
|
36
|
+
"entity": {
|
|
37
|
+
"type": "App::Folder",
|
|
38
|
+
"id": "handbook"
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
"conditions": [
|
|
43
|
+
{
|
|
44
|
+
"kind": "when",
|
|
45
|
+
"body": {
|
|
46
|
+
"&&": {
|
|
47
|
+
"left": {
|
|
48
|
+
"==": {
|
|
49
|
+
"left": {
|
|
50
|
+
".": {
|
|
51
|
+
"left": {
|
|
52
|
+
"Var": "resource"
|
|
53
|
+
},
|
|
54
|
+
"attr": "owner"
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
"right": {
|
|
58
|
+
"Var": "principal"
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
"right": {
|
|
63
|
+
"==": {
|
|
64
|
+
"left": {
|
|
65
|
+
".": {
|
|
66
|
+
"left": {
|
|
67
|
+
"Var": "context"
|
|
68
|
+
},
|
|
69
|
+
"attr": "mfa"
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
"right": {
|
|
73
|
+
"Value": true
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"kind": "when",
|
|
82
|
+
"body": {
|
|
83
|
+
"==": {
|
|
84
|
+
"left": {
|
|
85
|
+
".": {
|
|
86
|
+
"left": {
|
|
87
|
+
"Var": "principal"
|
|
88
|
+
},
|
|
89
|
+
"attr": "department"
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
"right": {
|
|
93
|
+
"Value": "eng"
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
"kind": "unless",
|
|
100
|
+
"body": {
|
|
101
|
+
"==": {
|
|
102
|
+
"left": {
|
|
103
|
+
".": {
|
|
104
|
+
"left": {
|
|
105
|
+
"Var": "resource"
|
|
106
|
+
},
|
|
107
|
+
"attr": "classification"
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
"right": {
|
|
111
|
+
"Value": "secret"
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"kind": "unless",
|
|
118
|
+
"body": {
|
|
119
|
+
"isInRange": [
|
|
120
|
+
{
|
|
121
|
+
".": {
|
|
122
|
+
"left": {
|
|
123
|
+
"Var": "context"
|
|
124
|
+
},
|
|
125
|
+
"attr": "ip"
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
"ip": [
|
|
130
|
+
{
|
|
131
|
+
"Value": "10.0.0.0/8"
|
|
132
|
+
}
|
|
133
|
+
]
|
|
134
|
+
}
|
|
135
|
+
]
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
],
|
|
139
|
+
"annotations": {
|
|
140
|
+
"doc": "Everything the authoring model can carry, in one policy.",
|
|
141
|
+
"id": "full-grant",
|
|
142
|
+
"owner": "platform",
|
|
143
|
+
"ticket": "SEC-12"
|
|
144
|
+
}
|
|
145
|
+
},
|
|
146
|
+
"deny-anonymous": {
|
|
147
|
+
"effect": "forbid",
|
|
148
|
+
"principal": {
|
|
149
|
+
"op": "All"
|
|
150
|
+
},
|
|
151
|
+
"action": {
|
|
152
|
+
"op": "All"
|
|
153
|
+
},
|
|
154
|
+
"resource": {
|
|
155
|
+
"op": "All"
|
|
156
|
+
},
|
|
157
|
+
"conditions": [],
|
|
158
|
+
"annotations": {
|
|
159
|
+
"id": "deny-anonymous"
|
|
160
|
+
}
|
|
161
|
+
},
|
|
162
|
+
"quoted-note": {
|
|
163
|
+
"effect": "permit",
|
|
164
|
+
"principal": {
|
|
165
|
+
"op": "==",
|
|
166
|
+
"entity": {
|
|
167
|
+
"type": "App::ServiceAccount",
|
|
168
|
+
"id": "ci"
|
|
169
|
+
}
|
|
170
|
+
},
|
|
171
|
+
"action": {
|
|
172
|
+
"op": "in",
|
|
173
|
+
"entities": [
|
|
174
|
+
{
|
|
175
|
+
"type": "App::Action",
|
|
176
|
+
"id": "create"
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
"type": "App::Action",
|
|
180
|
+
"id": "approve"
|
|
181
|
+
}
|
|
182
|
+
]
|
|
183
|
+
},
|
|
184
|
+
"resource": {
|
|
185
|
+
"op": "All"
|
|
186
|
+
},
|
|
187
|
+
"conditions": [
|
|
188
|
+
{
|
|
189
|
+
"kind": "when",
|
|
190
|
+
"body": {
|
|
191
|
+
"==": {
|
|
192
|
+
"left": {
|
|
193
|
+
".": {
|
|
194
|
+
"left": {
|
|
195
|
+
"Var": "context"
|
|
196
|
+
},
|
|
197
|
+
"attr": "note"
|
|
198
|
+
}
|
|
199
|
+
},
|
|
200
|
+
"right": {
|
|
201
|
+
"Value": "a } b { c"
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
],
|
|
207
|
+
"annotations": {
|
|
208
|
+
"id": "quoted-note",
|
|
209
|
+
"note": "say \"hi\" \\ done"
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
},
|
|
213
|
+
"templates": {
|
|
214
|
+
"share-with-slots": {
|
|
215
|
+
"effect": "permit",
|
|
216
|
+
"principal": {
|
|
217
|
+
"op": "==",
|
|
218
|
+
"slot": "?principal"
|
|
219
|
+
},
|
|
220
|
+
"action": {
|
|
221
|
+
"op": "==",
|
|
222
|
+
"entity": {
|
|
223
|
+
"type": "App::Action",
|
|
224
|
+
"id": "share"
|
|
225
|
+
}
|
|
226
|
+
},
|
|
227
|
+
"resource": {
|
|
228
|
+
"op": "in",
|
|
229
|
+
"slot": "?resource"
|
|
230
|
+
},
|
|
231
|
+
"conditions": [],
|
|
232
|
+
"annotations": {
|
|
233
|
+
"id": "share-with-slots"
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
},
|
|
237
|
+
"templateLinks": []
|
|
238
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
@id("owner-read")
|
|
2
|
+
@doc("Owners always read their own documents.")
|
|
3
|
+
permit (
|
|
4
|
+
principal is App::User,
|
|
5
|
+
action in [App::Action::"read", App::Action::"list"],
|
|
6
|
+
resource is App::Document
|
|
7
|
+
)
|
|
8
|
+
when { resource.owner == principal };
|
|
9
|
+
|
|
10
|
+
@id("public-read")
|
|
11
|
+
permit (
|
|
12
|
+
principal is App::User,
|
|
13
|
+
action == App::Action::"read",
|
|
14
|
+
resource is App::Document
|
|
15
|
+
)
|
|
16
|
+
when { resource.public == true }
|
|
17
|
+
when { context.mfa == true };
|
|
18
|
+
|
|
19
|
+
@id("owner-write")
|
|
20
|
+
permit (
|
|
21
|
+
principal is App::User,
|
|
22
|
+
action == App::Action::"write",
|
|
23
|
+
resource is App::Document
|
|
24
|
+
)
|
|
25
|
+
when { resource.owner == principal }
|
|
26
|
+
unless { context.mfa == false };
|
|
27
|
+
|
|
28
|
+
@id("restrict-delete")
|
|
29
|
+
forbid (
|
|
30
|
+
principal,
|
|
31
|
+
action == App::Action::"delete",
|
|
32
|
+
resource is App::Document
|
|
33
|
+
)
|
|
34
|
+
when { resource.classification == "confidential" }
|
|
35
|
+
unless { principal == App::User::"archivist" };
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
// Plugin
|
|
2
|
+
export { cedarPlugin } from "./plugin";
|
|
3
|
+
|
|
4
|
+
// Serializer
|
|
5
|
+
export { cedarSerializer, policyIdFromLogicalName, resolvePolicyId, cedarPolicyRecords } from "./serializer";
|
|
6
|
+
export { CEDAR_POLICY_TYPE, CEDAR_JSON_FILENAME } from "./serializer";
|
|
7
|
+
export type { CedarEffect, CedarScope, CedarPolicyProps, CedarPolicyRecord } from "./serializer";
|
|
8
|
+
|
|
9
|
+
// AVP embedding (#1652) — the typed statement an `AWS::VerifiedPermissions::Policy`
|
|
10
|
+
// carries, without a dependency on the aws lexicon. See src/avp/embed.ts.
|
|
11
|
+
export {
|
|
12
|
+
avpStatement,
|
|
13
|
+
avpStatementJSON,
|
|
14
|
+
avpPolicyDefinition,
|
|
15
|
+
avpPolicyResource,
|
|
16
|
+
avpPolicySet,
|
|
17
|
+
} from "./avp/embed";
|
|
18
|
+
export type {
|
|
19
|
+
AvpEmbedOptions,
|
|
20
|
+
AvpPolicyDefinition,
|
|
21
|
+
AvpPolicyResource,
|
|
22
|
+
AvpStaticDefinition,
|
|
23
|
+
} from "./avp/embed";
|
|
24
|
+
|
|
25
|
+
// The AVP ownership channel (#1652, chant #1348). Design record: src/avp/OWNERSHIP.md.
|
|
26
|
+
export {
|
|
27
|
+
AVP_OWNERSHIP_KEYS,
|
|
28
|
+
AVP_POLICY_ID_KEY,
|
|
29
|
+
AVP_DESCRIPTION_MAX,
|
|
30
|
+
encodeOwnershipDescription,
|
|
31
|
+
decodeOwnershipDescription,
|
|
32
|
+
ownershipFromDescription,
|
|
33
|
+
ownershipFromStoreTags,
|
|
34
|
+
descriptionIsOwned,
|
|
35
|
+
storeOwnershipTags,
|
|
36
|
+
} from "./avp/ownership";
|
|
37
|
+
export type { DecodedDescription } from "./avp/ownership";
|
|
38
|
+
|
|
39
|
+
// AVP lifecycle readers (#1652).
|
|
40
|
+
export { describeAvpResources } from "./avp/describe-resources";
|
|
41
|
+
export { observeAvpAmbient, AVP_AMBIENT_KINDS } from "./avp/ambient";
|
|
42
|
+
export { exportAvpResources, policyToResourceIR } from "./avp/live-export";
|
|
43
|
+
export { resolvePolicyStoreId, AVP_POLICY_STORE_ENV } from "./avp/store";
|
|
44
|
+
|
|
45
|
+
export { policySetJSON, escapeCedarString } from "./serializer";
|
|
46
|
+
export type { CedarPolicySetJSON } from "./serializer";
|
|
47
|
+
|
|
48
|
+
// Import / reconcile (#1653) — `.cedar` text and the JSON policy-set envelope
|
|
49
|
+
// in, authoring TypeScript out.
|
|
50
|
+
export { CedarParser, isPolicySetEnvelope } from "./import/parser";
|
|
51
|
+
export type { CedarParseResult, CedarPolicyIR, CedarEntityKind } from "./import/parser";
|
|
52
|
+
export { CedarGenerator, loadActionConstants, sanitizeName, CEDAR_PACKAGE } from "./import/generator";
|
|
53
|
+
export type { CedarGenerateOptions, CedarGenerateResult } from "./import/generator";
|
|
54
|
+
export { CedarTemplateParser, CedarTemplateGenerator } from "./import/adapter";
|
|
55
|
+
export { detectTemplate } from "./detect";
|
|
56
|
+
|
|
57
|
+
// Lint rules
|
|
58
|
+
export { rules as cedarLintRules } from "./lint/rules";
|
|
59
|
+
|
|
60
|
+
// Packaging pipeline (for external tooling)
|
|
61
|
+
export { packageLexicon } from "./codegen/package";
|
|
62
|
+
export type { PackageOptions, PackageResult } from "./codegen/package";
|
|
63
|
+
|
|
64
|
+
// The `cedar` config namespace (#1344). Importing this package is what brings
|
|
65
|
+
// the key into ChantConfig, so a `chant.config.ts` that sets it compiles.
|
|
66
|
+
export { cedarConfigSchema, loadCedarConfig, CEDAR_DEFAULT_SCHEMA_PATH } from "./config";
|
|
67
|
+
export type { CedarConfig } from "./config";
|
|
68
|
+
|
|
69
|
+
// Upstream pin — the cedar-wasm package version and the Cedar language
|
|
70
|
+
// version it implements (#1650).
|
|
71
|
+
export { CEDAR_WASM_VERSION, CEDAR_LANG_VERSION } from "./spec/pin";
|
|
72
|
+
|
|
73
|
+
// Schema coverage — is every schema declaration reachable from the generated
|
|
74
|
+
// artifacts? Policy coverage below asks the other half.
|
|
75
|
+
export { computeCedarCoverage, formatCedarCoverage, analyzeCedarCoverage } from "./coverage";
|
|
76
|
+
export type { CedarCoverageReport, CedarCoverageItem } from "./coverage";
|
|
77
|
+
|
|
78
|
+
// Policy coverage — which schema declarations the built policy set can apply
|
|
79
|
+
// to. Backs the `cedar:coverage` MCP tool.
|
|
80
|
+
export { computePolicyCoverage, formatPolicyCoverage } from "./mcp/policy-coverage";
|
|
81
|
+
export type {
|
|
82
|
+
CedarPolicyCoverageReport,
|
|
83
|
+
CedarPolicyCoverageItem,
|
|
84
|
+
CedarPolicyCoverageOptions,
|
|
85
|
+
} from "./mcp/policy-coverage";
|
|
86
|
+
|
|
87
|
+
// Composites — the repeated policy shapes Cedar itself has nowhere to put.
|
|
88
|
+
export * from "./composites/index";
|
|
89
|
+
|
|
90
|
+
// `chant init --lexicon cedar --template <name>` scaffolds.
|
|
91
|
+
export { cedarInitTemplates, CEDAR_INIT_TEMPLATES } from "./init-templates";
|
|
92
|
+
|
|
93
|
+
// Generated entity types, actions and the Policy authoring class (#1650).
|
|
94
|
+
export * from "./generated/index";
|