camunda-cloud-idac 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,78 @@
1
+ export const PROTECTED_ROLE_ID = "admin";
2
+ export const PROTECTED_TENANT_ID = "<default>";
3
+ /**
4
+ * The client this tool itself authenticates as (from CAMUNDA_CLIENT_ID, the same
5
+ * variable createCamundaClientLoose() reads). Its assignment to the admin role is
6
+ * protected from removal so a full reset can never lock the tool itself out.
7
+ * Deliberately NOT self-healing (per explicit product decision): if this client
8
+ * isn't already assigned to the admin role, this tool will not assign it - it
9
+ * only guards an existing assignment from being pruned away.
10
+ */
11
+ function getGuardianClientId() {
12
+ return process.env.CAMUNDA_CLIENT_ID;
13
+ }
14
+ /**
15
+ * Unconditional safety filter, applied after diffing regardless of spec content.
16
+ * This is deliberately NOT a "skip if the spec doesn't mention admin" heuristic
17
+ * inside diff.ts: if the spec never mentions the admin role at all, the raw diff
18
+ * would otherwise queue every one of its authorizations for deletion in prune
19
+ * mode (they're simply "not in spec" = "extra"). Keeping the guard here, as a
20
+ * pure post-filter over the already-computed action list, means it can't be
21
+ * bypassed by any particular shape of spec and is the one place to audit to
22
+ * trust the invariant holds.
23
+ *
24
+ * Current invariants (narrowed by explicit product decision - the "admin" group,
25
+ * if one exists, is no longer specially protected; only the "admin" role is):
26
+ * 1. The "admin" role itself is never deleted.
27
+ * 2. The "admin" role's authorizations are fully hands-off: never created,
28
+ * updated, or deleted by this tool - not merely protected from deletion.
29
+ * 3. This tool's own client (CAMUNDA_CLIENT_ID) never loses its assignment to
30
+ * the admin role, so a full reset can't lock the tool out of the cluster it
31
+ * just reset. Every other role<->client pair (including other clients
32
+ * assigned to the admin role) is unaffected by this rule.
33
+ * 4. The `<default>` system tenant is never deleted (defense in depth - the API
34
+ * already rejects this server-side).
35
+ * 5. The "admin" role never loses its assignment to the `<default>` tenant, so
36
+ * a full `--prune` reset can never leave the admin role without access to
37
+ * the default tenant. Every other tenant<->role pair (including the admin
38
+ * role's assignment to any other tenant) is unaffected by this rule.
39
+ *
40
+ * Only entity-delete/authorization-mutation/the two guarded unassign edges
41
+ * (unassign-role-client, unassign-tenant-role) are ever blocked. Every other
42
+ * unassign-* action - including removing other roles/members from the admin
43
+ * role, or removing a non-guardian client from it - passes through untouched.
44
+ */
45
+ export function applyProtections(actions) {
46
+ const warnings = [];
47
+ const guardianClientId = getGuardianClientId();
48
+ const kept = actions.filter((action) => {
49
+ const block = (reason) => {
50
+ warnings.push(`BLOCKED (${reason}): ${action.description}`);
51
+ return false;
52
+ };
53
+ const target = action.target;
54
+ if (target.kind === "delete-role" && target.roleId === PROTECTED_ROLE_ID) {
55
+ return block(`the "${PROTECTED_ROLE_ID}" role must never be deleted`);
56
+ }
57
+ if (target.kind === "delete-tenant" && target.tenantId === PROTECTED_TENANT_ID) {
58
+ return block(`the ${PROTECTED_TENANT_ID} system tenant must never be deleted`);
59
+ }
60
+ if (target.kind === "authorization" && target.ownerType === "ROLE" && target.ownerId === PROTECTED_ROLE_ID) {
61
+ return block(`authorizations of the "${PROTECTED_ROLE_ID}" role must never be created, updated, or deleted`);
62
+ }
63
+ if (target.kind === "unassign-role-client" &&
64
+ target.roleId === PROTECTED_ROLE_ID &&
65
+ guardianClientId !== undefined &&
66
+ target.clientId === guardianClientId) {
67
+ return block(`this tool's own client ("${guardianClientId}") must keep the "${PROTECTED_ROLE_ID}" role, or a full reset would lock the tool out`);
68
+ }
69
+ if (target.kind === "unassign-tenant-role" &&
70
+ target.tenantId === PROTECTED_TENANT_ID &&
71
+ target.roleId === PROTECTED_ROLE_ID) {
72
+ return block(`the "${PROTECTED_ROLE_ID}" role must never be unassigned from the ${PROTECTED_TENANT_ID} tenant`);
73
+ }
74
+ return true;
75
+ });
76
+ return { actions: kept, warnings };
77
+ }
78
+ //# sourceMappingURL=protect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protect.js","sourceRoot":"","sources":["../../src/reconcile/protect.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,iBAAiB,GAAG,OAAO,CAAC;AACzC,MAAM,CAAC,MAAM,mBAAmB,GAAG,WAAW,CAAC;AAE/C;;;;;;;GAOG;AACH,SAAS,mBAAmB;IAC1B,OAAO,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;AACvC,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAwB;IACvD,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,MAAM,gBAAgB,GAAG,mBAAmB,EAAE,CAAC;IAE/C,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE;QACrC,MAAM,KAAK,GAAG,CAAC,MAAc,EAAE,EAAE;YAC/B,QAAQ,CAAC,IAAI,CAAC,YAAY,MAAM,MAAM,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;YAC5D,OAAO,KAAK,CAAC;QACf,CAAC,CAAC;QAEF,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QAE7B,IAAI,MAAM,CAAC,IAAI,KAAK,aAAa,IAAI,MAAM,CAAC,MAAM,KAAK,iBAAiB,EAAE,CAAC;YACzE,OAAO,KAAK,CAAC,QAAQ,iBAAiB,8BAA8B,CAAC,CAAC;QACxE,CAAC;QAED,IAAI,MAAM,CAAC,IAAI,KAAK,eAAe,IAAI,MAAM,CAAC,QAAQ,KAAK,mBAAmB,EAAE,CAAC;YAC/E,OAAO,KAAK,CAAC,OAAO,mBAAmB,sCAAsC,CAAC,CAAC;QACjF,CAAC;QAED,IAAI,MAAM,CAAC,IAAI,KAAK,eAAe,IAAI,MAAM,CAAC,SAAS,KAAK,MAAM,IAAI,MAAM,CAAC,OAAO,KAAK,iBAAiB,EAAE,CAAC;YAC3G,OAAO,KAAK,CAAC,0BAA0B,iBAAiB,mDAAmD,CAAC,CAAC;QAC/G,CAAC;QAED,IACE,MAAM,CAAC,IAAI,KAAK,sBAAsB;YACtC,MAAM,CAAC,MAAM,KAAK,iBAAiB;YACnC,gBAAgB,KAAK,SAAS;YAC9B,MAAM,CAAC,QAAQ,KAAK,gBAAgB,EACpC,CAAC;YACD,OAAO,KAAK,CACV,4BAA4B,gBAAgB,qBAAqB,iBAAiB,iDAAiD,CACpI,CAAC;QACJ,CAAC;QAED,IACE,MAAM,CAAC,IAAI,KAAK,sBAAsB;YACtC,MAAM,CAAC,QAAQ,KAAK,mBAAmB;YACvC,MAAM,CAAC,MAAM,KAAK,iBAAiB,EACnC,CAAC;YACD,OAAO,KAAK,CAAC,QAAQ,iBAAiB,4CAA4C,mBAAmB,SAAS,CAAC,CAAC;QAClH,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;IAEH,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;AACrC,CAAC"}
@@ -0,0 +1,18 @@
1
+ export const DESTRUCTIVE_KINDS = new Set([
2
+ "delete-tenant",
3
+ "delete-role",
4
+ "delete-group",
5
+ "delete-mapping-rule",
6
+ "delete-authorization",
7
+ "unassign-role-mapping-rule",
8
+ "unassign-role-group",
9
+ "unassign-group-mapping-rule",
10
+ "unassign-group-user",
11
+ "unassign-group-client",
12
+ "unassign-role-user",
13
+ "unassign-role-client",
14
+ "unassign-tenant-role",
15
+ "unassign-tenant-group",
16
+ "unassign-tenant-mapping-rule",
17
+ ]);
18
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/reconcile/types.ts"],"names":[],"mappings":"AAiGA,MAAM,CAAC,MAAM,iBAAiB,GAA4B,IAAI,GAAG,CAAa;IAC5E,eAAe;IACf,aAAa;IACb,cAAc;IACd,qBAAqB;IACrB,sBAAsB;IACtB,4BAA4B;IAC5B,qBAAqB;IACrB,6BAA6B;IAC7B,qBAAqB;IACrB,uBAAuB;IACvB,oBAAoB;IACpB,sBAAsB;IACtB,sBAAsB;IACtB,uBAAuB;IACvB,8BAA8B;CAC/B,CAAC,CAAC"}
@@ -0,0 +1,46 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { parse as parseYaml, YAMLParseError } from "yaml";
3
+ import { Spec } from "./schema.js";
4
+ export class SpecValidationError extends Error {
5
+ filePath;
6
+ issues;
7
+ constructor(filePath, issues) {
8
+ super(`Invalid spec at ${filePath}:\n${issues.map((i) => ` - ${i}`).join("\n")}`);
9
+ this.filePath = filePath;
10
+ this.issues = issues;
11
+ this.name = "SpecValidationError";
12
+ }
13
+ }
14
+ function formatZodError(error) {
15
+ return error.issues.map((issue) => {
16
+ const path = issue.path.join(".");
17
+ return path ? `${path}: ${issue.message}` : issue.message;
18
+ });
19
+ }
20
+ export async function loadSpec(filePath) {
21
+ let raw;
22
+ try {
23
+ raw = await readFile(filePath, "utf-8");
24
+ }
25
+ catch (err) {
26
+ throw new SpecValidationError(filePath, [
27
+ err instanceof Error ? err.message : `Could not read file: ${String(err)}`,
28
+ ]);
29
+ }
30
+ let parsed;
31
+ try {
32
+ parsed = parseYaml(raw);
33
+ }
34
+ catch (err) {
35
+ if (err instanceof YAMLParseError) {
36
+ throw new SpecValidationError(filePath, [err.message]);
37
+ }
38
+ throw err;
39
+ }
40
+ const result = Spec.safeParse(parsed);
41
+ if (!result.success) {
42
+ throw new SpecValidationError(filePath, formatZodError(result.error));
43
+ }
44
+ return result.data;
45
+ }
46
+ //# sourceMappingURL=load.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load.js","sourceRoot":"","sources":["../../src/spec/load.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,cAAc,EAAE,MAAM,MAAM,CAAC;AAE1D,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAGnC,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IAE1B;IACA;IAFlB,YACkB,QAAgB,EAChB,MAAgB;QAEhC,KAAK,CAAC,mBAAmB,QAAQ,MAAM,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAHnE,aAAQ,GAAR,QAAQ,CAAQ;QAChB,WAAM,GAAN,MAAM,CAAU;QAGhC,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;IACpC,CAAC;CACF;AAED,SAAS,cAAc,CAAC,KAAe;IACrC,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QAChC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAClC,OAAO,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC;IAC5D,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,QAAgB;IAC7C,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC1C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,mBAAmB,CAAC,QAAQ,EAAE;YACtC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,wBAAwB,MAAM,CAAC,GAAG,CAAC,EAAE;SAC3E,CAAC,CAAC;IACL,CAAC;IAED,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;IAC1B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,cAAc,EAAE,CAAC;YAClC,MAAM,IAAI,mBAAmB,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;QACzD,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IACtC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,IAAI,mBAAmB,CAAC,QAAQ,EAAE,cAAc,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IACxE,CAAC;IAED,OAAO,MAAM,CAAC,IAAI,CAAC;AACrB,CAAC"}
@@ -0,0 +1,274 @@
1
+ import { z } from "zod";
2
+ // Copied verbatim from node_modules/@camunda8/orchestration-cluster-api's shipped
3
+ // .d.ts (OwnerTypeEnum / ResourceTypeEnum / PermissionTypeEnum). Re-check these
4
+ // against the installed package whenever the pinned SDK version in package.json
5
+ // changes - a drifted enum here would silently accept specs the live API rejects.
6
+ export const OwnerType = z.enum(["USER", "CLIENT", "ROLE", "GROUP", "MAPPING_RULE", "UNSPECIFIED"]);
7
+ export const ResourceType = z.enum([
8
+ "AUDIT_LOG",
9
+ "AUTHORIZATION",
10
+ "BATCH",
11
+ "CLUSTER_VARIABLE",
12
+ "COMPONENT",
13
+ "DECISION_DEFINITION",
14
+ "DECISION_REQUIREMENTS_DEFINITION",
15
+ "DOCUMENT",
16
+ "EXPRESSION",
17
+ "GLOBAL_LISTENER",
18
+ "GROUP",
19
+ "MAPPING_RULE",
20
+ "MESSAGE",
21
+ "PROCESS_DEFINITION",
22
+ "RESOURCE",
23
+ "ROLE",
24
+ "SYSTEM",
25
+ "TENANT",
26
+ "USER",
27
+ "USER_TASK",
28
+ ]);
29
+ export const PermissionType = z.enum([
30
+ "ACCESS",
31
+ "CANCEL_PROCESS_INSTANCE",
32
+ "CLAIM",
33
+ "CLAIM_USER_TASK",
34
+ "COMPLETE",
35
+ "COMPLETE_USER_TASK",
36
+ "CREATE",
37
+ "CREATE_BATCH_OPERATION_CANCEL_PROCESS_INSTANCE",
38
+ "CREATE_BATCH_OPERATION_DELETE_DECISION_DEFINITION",
39
+ "CREATE_BATCH_OPERATION_DELETE_DECISION_INSTANCE",
40
+ "CREATE_BATCH_OPERATION_DELETE_PROCESS_DEFINITION",
41
+ "CREATE_BATCH_OPERATION_DELETE_PROCESS_INSTANCE",
42
+ "CREATE_BATCH_OPERATION_MIGRATE_PROCESS_INSTANCE",
43
+ "CREATE_BATCH_OPERATION_MODIFY_PROCESS_INSTANCE",
44
+ "CREATE_BATCH_OPERATION_RESOLVE_INCIDENT",
45
+ "CREATE_DECISION_INSTANCE",
46
+ "CREATE_PROCESS_INSTANCE",
47
+ "CREATE_TASK_LISTENER",
48
+ "DELETE",
49
+ "DELETE_DECISION_INSTANCE",
50
+ "DELETE_DRD",
51
+ "DELETE_FORM",
52
+ "DELETE_PROCESS",
53
+ "DELETE_PROCESS_INSTANCE",
54
+ "DELETE_RESOURCE",
55
+ "DELETE_TASK_LISTENER",
56
+ "EVALUATE",
57
+ "MODIFY_PROCESS_INSTANCE",
58
+ "READ",
59
+ "READ_DECISION_DEFINITION",
60
+ "READ_DECISION_INSTANCE",
61
+ "READ_JOB_METRIC",
62
+ "READ_PROCESS_DEFINITION",
63
+ "READ_PROCESS_INSTANCE",
64
+ "READ_USAGE_METRIC",
65
+ "READ_USER_TASK",
66
+ "READ_TASK_LISTENER",
67
+ "UPDATE",
68
+ "UPDATE_PROCESS_INSTANCE",
69
+ "UPDATE_USER_TASK",
70
+ "UPDATE_TASK_LISTENER",
71
+ ]);
72
+ // Entities that can own an authorization and are also declared as first-class
73
+ // entities in this spec (used by the referential-integrity check below).
74
+ const OWNER_TYPES_WITH_DECLARED_ENTITIES = new Set(["ROLE", "GROUP", "MAPPING_RULE"]);
75
+ // .strict() on every object below is deliberate, not incidental: zod's default
76
+ // z.object() silently drops unrecognized keys instead of rejecting them, which
77
+ // would let a typo (e.g. `mappingRuleId: [...]` instead of `mappingRules: [...]`
78
+ // on a group) parse "successfully" while silently doing nothing - exactly the
79
+ // class of error this tool uses zod to prevent in the first place.
80
+ const MappingRuleSpec = z
81
+ .object({
82
+ mappingRuleId: z.string().min(1),
83
+ claimName: z.string().min(1),
84
+ claimValue: z.string().min(1),
85
+ name: z.string().optional(),
86
+ })
87
+ .strict();
88
+ const GroupSpec = z
89
+ .object({
90
+ groupId: z.string().min(1),
91
+ name: z.string().min(1),
92
+ description: z.string().optional(),
93
+ mappingRules: z.array(z.string()).default([]),
94
+ // Direct membership, not modeled via mapping rules/OIDC claims. Usernames and
95
+ // client IDs aren't declared entities elsewhere in this spec (unlike
96
+ // roles/groups/mappingRules), so there's no referential-integrity check for
97
+ // these - any string is accepted, matching how authorization owners of type
98
+ // USER/CLIENT are handled.
99
+ users: z.array(z.string()).default([]),
100
+ clients: z.array(z.string()).default([]),
101
+ })
102
+ .strict();
103
+ const RoleSpec = z
104
+ .object({
105
+ roleId: z.string().min(1),
106
+ name: z.string().min(1),
107
+ description: z.string().optional(),
108
+ mappingRules: z.array(z.string()).default([]),
109
+ groups: z.array(z.string()).default([]),
110
+ // Direct membership - not modeled via mapping rules/OIDC claims, no
111
+ // referential-integrity check (same rationale as GroupSpec.users/clients above).
112
+ users: z.array(z.string()).default([]),
113
+ clients: z.array(z.string()).default([]),
114
+ })
115
+ .strict();
116
+ const TenantSpec = z
117
+ .object({
118
+ tenantId: z.string().min(1),
119
+ name: z.string().min(1),
120
+ description: z.string().optional(),
121
+ roles: z.array(z.string()).default([]),
122
+ groups: z.array(z.string()).default([]),
123
+ mappingRules: z.array(z.string()).default([]),
124
+ })
125
+ .strict();
126
+ const AuthorizationSpec = z
127
+ .object({
128
+ ownerType: OwnerType,
129
+ ownerId: z.string().min(1),
130
+ resourceType: ResourceType,
131
+ resourceId: z.string().min(1),
132
+ permissions: z.array(PermissionType).min(1),
133
+ })
134
+ .strict();
135
+ const RawSpec = z
136
+ .object({
137
+ tenants: z.array(TenantSpec).default([]),
138
+ roles: z.array(RoleSpec).default([]),
139
+ groups: z.array(GroupSpec).default([]),
140
+ mappingRules: z.array(MappingRuleSpec).default([]),
141
+ authorizations: z.array(AuthorizationSpec).default([]),
142
+ })
143
+ .strict();
144
+ function findDuplicates(ids) {
145
+ const seen = new Set();
146
+ const dupes = new Set();
147
+ for (const id of ids) {
148
+ if (seen.has(id))
149
+ dupes.add(id);
150
+ seen.add(id);
151
+ }
152
+ return [...dupes];
153
+ }
154
+ export const Spec = RawSpec.superRefine((spec, ctx) => {
155
+ const mappingRuleIds = new Set(spec.mappingRules.map((m) => m.mappingRuleId));
156
+ const groupIds = new Set(spec.groups.map((g) => g.groupId));
157
+ const roleIds = new Set(spec.roles.map((r) => r.roleId));
158
+ // Rule 7: no duplicate IDs within each entity array.
159
+ for (const [label, ids] of [
160
+ ["tenants[].tenantId", spec.tenants.map((t) => t.tenantId)],
161
+ ["roles[].roleId", spec.roles.map((r) => r.roleId)],
162
+ ["groups[].groupId", spec.groups.map((g) => g.groupId)],
163
+ ["mappingRules[].mappingRuleId", spec.mappingRules.map((m) => m.mappingRuleId)],
164
+ ]) {
165
+ for (const dupe of findDuplicates(ids)) {
166
+ ctx.addIssue({
167
+ code: "custom",
168
+ path: [label],
169
+ message: `Duplicate ${label} value: "${dupe}"`,
170
+ });
171
+ }
172
+ }
173
+ // Rules 1-3: role/group references to mapping rules and groups.
174
+ spec.roles.forEach((role, i) => {
175
+ role.mappingRules.forEach((id, j) => {
176
+ if (!mappingRuleIds.has(id)) {
177
+ ctx.addIssue({
178
+ code: "custom",
179
+ path: ["roles", i, "mappingRules", j],
180
+ message: `roles[${i}] ("${role.roleId}") references unknown mappingRuleId "${id}"`,
181
+ });
182
+ }
183
+ });
184
+ role.groups.forEach((id, j) => {
185
+ if (!groupIds.has(id)) {
186
+ ctx.addIssue({
187
+ code: "custom",
188
+ path: ["roles", i, "groups", j],
189
+ message: `roles[${i}] ("${role.roleId}") references unknown groupId "${id}"`,
190
+ });
191
+ }
192
+ });
193
+ });
194
+ spec.groups.forEach((group, i) => {
195
+ group.mappingRules.forEach((id, j) => {
196
+ if (!mappingRuleIds.has(id)) {
197
+ ctx.addIssue({
198
+ code: "custom",
199
+ path: ["groups", i, "mappingRules", j],
200
+ message: `groups[${i}] ("${group.groupId}") references unknown mappingRuleId "${id}"`,
201
+ });
202
+ }
203
+ });
204
+ });
205
+ // Rules 4-5: tenant references to roles and groups.
206
+ spec.tenants.forEach((tenant, i) => {
207
+ tenant.roles.forEach((id, j) => {
208
+ if (!roleIds.has(id)) {
209
+ ctx.addIssue({
210
+ code: "custom",
211
+ path: ["tenants", i, "roles", j],
212
+ message: `tenants[${i}] ("${tenant.tenantId}") references unknown roleId "${id}"`,
213
+ });
214
+ }
215
+ });
216
+ tenant.groups.forEach((id, j) => {
217
+ if (!groupIds.has(id)) {
218
+ ctx.addIssue({
219
+ code: "custom",
220
+ path: ["tenants", i, "groups", j],
221
+ message: `tenants[${i}] ("${tenant.tenantId}") references unknown groupId "${id}"`,
222
+ });
223
+ }
224
+ });
225
+ tenant.mappingRules.forEach((id, j) => {
226
+ if (!mappingRuleIds.has(id)) {
227
+ ctx.addIssue({
228
+ code: "custom",
229
+ path: ["tenants", i, "mappingRules", j],
230
+ message: `tenants[${i}] ("${tenant.tenantId}") references unknown mappingRuleId "${id}"`,
231
+ });
232
+ }
233
+ });
234
+ });
235
+ // Rule 6: authorization owner must exist among declared entities, when the
236
+ // owner type corresponds to a declared entity type in this spec.
237
+ const idsByOwnerType = {
238
+ ROLE: roleIds,
239
+ GROUP: groupIds,
240
+ MAPPING_RULE: mappingRuleIds,
241
+ };
242
+ spec.authorizations.forEach((auth, i) => {
243
+ if (OWNER_TYPES_WITH_DECLARED_ENTITIES.has(auth.ownerType)) {
244
+ const ids = idsByOwnerType[auth.ownerType];
245
+ if (!ids.has(auth.ownerId)) {
246
+ ctx.addIssue({
247
+ code: "custom",
248
+ path: ["authorizations", i, "ownerId"],
249
+ message: `authorizations[${i}] references unknown ${auth.ownerType} ownerId "${auth.ownerId}"`,
250
+ });
251
+ }
252
+ }
253
+ });
254
+ // Rule 8: no two authorization entries with the same tuple but different permissions.
255
+ const tupleToPermissions = new Map();
256
+ spec.authorizations.forEach((auth, i) => {
257
+ const key = `${auth.ownerType}::${auth.ownerId}::${auth.resourceType}::${auth.resourceId}`;
258
+ const existing = tupleToPermissions.get(key);
259
+ if (!existing) {
260
+ tupleToPermissions.set(key, { index: i, permissions: auth.permissions });
261
+ return;
262
+ }
263
+ const sameSet = existing.permissions.length === auth.permissions.length &&
264
+ new Set(existing.permissions).size === new Set([...existing.permissions, ...auth.permissions]).size;
265
+ if (!sameSet) {
266
+ ctx.addIssue({
267
+ code: "custom",
268
+ path: ["authorizations", i],
269
+ message: `authorizations[${i}] duplicates the tuple (${auth.ownerType}, ${auth.ownerId}, ${auth.resourceType}, ${auth.resourceId}) already declared at authorizations[${existing.index}] with different permissions`,
270
+ });
271
+ }
272
+ });
273
+ });
274
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/spec/schema.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "camunda-cloud-idac",
3
+ "version": "1.0.0",
4
+ "description": "Identity-as-code reconciler for Camunda 8 (tenants, roles, groups, mapping rules, authorizations)",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "author": "Jan Rohwer",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/janhuddel/camunda-cloud-idac.git"
11
+ },
12
+ "homepage": "https://github.com/janhuddel/camunda-cloud-idac#readme",
13
+ "bugs": {
14
+ "url": "https://github.com/janhuddel/camunda-cloud-idac/issues"
15
+ },
16
+ "keywords": [
17
+ "camunda",
18
+ "camunda-8",
19
+ "zeebe",
20
+ "identity-as-code",
21
+ "iac",
22
+ "cli"
23
+ ],
24
+ "bin": {
25
+ "camunda-idac": "./dist/cli.js",
26
+ "cci": "./dist/cli.js"
27
+ },
28
+ "files": [
29
+ "dist"
30
+ ],
31
+ "scripts": {
32
+ "build": "tsc -p tsconfig.json",
33
+ "dev": "tsx src/cli.ts",
34
+ "typecheck": "tsc --noEmit -p tsconfig.typecheck.json",
35
+ "test": "vitest run",
36
+ "prepublishOnly": "npm run typecheck && npm test && npm run build"
37
+ },
38
+ "dependencies": {
39
+ "@camunda8/orchestration-cluster-api": "9.1.5",
40
+ "commander": "^12.1.0",
41
+ "yaml": "^2.6.1",
42
+ "zod": "^4.0.0"
43
+ },
44
+ "devDependencies": {
45
+ "@types/node": "^20.17.0",
46
+ "tsx": "^4.19.2",
47
+ "typescript": "^5.7.2",
48
+ "vitest": "^2.1.8"
49
+ },
50
+ "engines": {
51
+ "node": ">=20.6.0"
52
+ }
53
+ }