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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Jan Rohwer
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,117 @@
1
+ # camunda-cloud-idac
2
+
3
+ Identity-as-code reconciler for Camunda 8: declares tenants, roles, groups,
4
+ mapping rules, and authorizations in a YAML spec, then reconciles a live
5
+ cluster against it via `@camunda8/orchestration-cluster-api`.
6
+
7
+ Complements (does not replace) Camunda 8.8's built-in "Identity as Code"
8
+ Spring Boot feature, which only creates missing entities once at cluster
9
+ boot and never updates or deletes anything. This tool can run anytime
10
+ against a live cluster, updates entities in place, and supports pruning
11
+ (`--prune`) to delete anything not in the spec.
12
+
13
+ **Hard safety guarantee** (see `src/reconcile/protect.ts` - the single audit
14
+ point for all of this, applied unconditionally after diffing regardless of
15
+ spec content):
16
+
17
+ - The `admin` role is never deleted.
18
+ - The `admin` role's authorizations are fully hands-off: never created,
19
+ updated, or deleted by this tool at all - not merely protected from
20
+ deletion.
21
+ - This tool's own client (`CAMUNDA_CLIENT_ID`) never loses its assignment to
22
+ the `admin` role, so a full `--prune` reset can never lock the tool itself
23
+ out. This guard only protects an *existing* assignment from removal - it
24
+ does not proactively assign the client if that assignment is missing.
25
+ - The `<default>` system tenant is never deleted (the API already rejects
26
+ this server-side; this is defense in depth).
27
+
28
+ The `admin` *group* (if one exists) has **no special protection** - it's
29
+ reconciled like any other group, including deletion under `--prune`. Adding
30
+ or removing members (users/clients/groups/mapping rules) on the `admin`
31
+ role is always fine and unaffected by any of the above; only deleting the
32
+ role itself, mutating its authorizations, or unassigning the tool's own
33
+ client from it are guarded.
34
+
35
+ ## Installation
36
+
37
+ Set the `CAMUNDA_*` connection env vars first (OAuth client credentials for
38
+ an M2M client with admin authorizations, cluster REST address, optional
39
+ mTLS) - see `.env.example` for the full list.
40
+
41
+ Run without installing:
42
+
43
+ ```sh
44
+ npx camunda-cloud-idac plan spec.yaml [--prune]
45
+ ```
46
+
47
+ Or install globally and use the `camunda-idac` (or shorter `cci`) command:
48
+
49
+ ```sh
50
+ npm install -g camunda-cloud-idac
51
+
52
+ camunda-idac validate spec.yaml
53
+ camunda-idac plan spec.yaml [--prune]
54
+ camunda-idac apply spec.yaml [--prune] [--yes]
55
+
56
+ # cci is an alias for camunda-idac
57
+ cci plan spec.yaml
58
+ ```
59
+
60
+ `--prune` absent = additive mode (default): only creates/updates, never
61
+ deletes. `apply` without `--yes` prints the plan and asks for interactive
62
+ confirmation; it refuses to run without `--yes` on a non-interactive shell
63
+ (CI), so a pipeline can never silently confirm a destructive prune.
64
+
65
+ ## Development
66
+
67
+ ```sh
68
+ npm install
69
+ cp .env.example .env # fill in CAMUNDA_* connection details, then export them
70
+
71
+ npx tsx src/cli.ts validate spec.yaml # schema + referential integrity only, no network
72
+ npx tsx src/cli.ts plan spec.yaml [--prune] # dry-run diff; exit 1 if there's drift (CI-friendly)
73
+ npx tsx src/cli.ts apply spec.yaml [--prune] [--yes]
74
+ ```
75
+
76
+ Build once for a compiled binary: `npm run build && node dist/cli.js ...`.
77
+
78
+ ## Spec format
79
+
80
+ See `test/fixtures/valid-spec.yaml` for a complete example. Top-level keys:
81
+ `tenants`, `roles`, `groups`, `mappingRules`, `authorizations` (all
82
+ optional, default to `[]`). The "container" entity is authoritative for its
83
+ own relationships - e.g. a role declares its own `groups`/`mappingRules`;
84
+ there's no reverse field - which avoids conflicting declarations by
85
+ construction.
86
+
87
+ Roles and groups can also declare direct `users`/`clients` membership (not
88
+ just mapping-rule/group-based provisioning) - useful for OIDC setups where
89
+ some principals are granted access by username/client ID rather than by an
90
+ IdP group claim. These aren't declared entities elsewhere in the spec, so
91
+ there's no referential-integrity check on them (any string is accepted).
92
+
93
+ ## Known limitations
94
+
95
+ - Direct **tenant**-to-user/client assignments aren't modeled by the spec
96
+ (only tenant-to-role/group are) - role- and group-level user/client
97
+ membership is fully supported and reconciled/cascaded by `--prune`, but
98
+ tenant-level direct user/client assignment is not.
99
+ - `plan`/`apply` read full current state once per run (not continuously),
100
+ so back-to-back runs within the cluster's eventual-consistency window
101
+ could theoretically miss very recent changes. Acceptable for an
102
+ interactively/CI-run admin CLI.
103
+
104
+ ## Testing
105
+
106
+ ```sh
107
+ npm run typecheck # includes test/ via tsconfig.typecheck.json
108
+ npm test # vitest - schema, diff, protect (safety-critical), order
109
+ ```
110
+
111
+ `test/reconcile/protect.test.ts` and `test/reconcile/diff.test.ts` are the
112
+ load-bearing suites: they cover the admin/default protection invariant and
113
+ the cascading-delete ordering directly.
114
+
115
+ No integration test suite against a live cluster yet - run the commands
116
+ above manually against a local `c8run` cluster before relying on `--prune`
117
+ in production, per the design plan's verification section.
@@ -0,0 +1,33 @@
1
+ import { createCamundaClientLoose } from "@camunda8/orchestration-cluster-api";
2
+ // The SDK also ships `createCamundaResultClient`, a proxy that mirrors CamundaClient
3
+ // but returns Promise<Result<T>> everywhere. Its own .d.ts marks it
4
+ // "@experimental ... not guaranteed to be fully tested or stable", so we deliberately
5
+ // do NOT depend on it here. Instead we use the throwing client and wrap calls
6
+ // ourselves with `toResult`, using the SDK's own `Result`/`ok` discriminant shape so
7
+ // the rest of the codebase still gets Result-style branching without depending on
8
+ // experimental SDK surface.
9
+ //
10
+ // We use the "Loose" client variant (all branded ID types - tenantId, authorizationKey,
11
+ // username - widened to plain string) rather than the strict one: every ID in this tool
12
+ // comes from user-authored YAML or from a prior search response, so the branded-type
13
+ // safety net buys nothing and would otherwise force casts at every tenant/authorization
14
+ // call site.
15
+ let client;
16
+ export function getClient() {
17
+ if (!client)
18
+ client = createCamundaClientLoose();
19
+ return client;
20
+ }
21
+ /** Skip eventual-consistency polling: every get/search in this tool re-reads full
22
+ * current state right before diffing, so waiting mid-computation buys nothing. */
23
+ export const NO_WAIT = { consistency: { waitUpToMs: 0 } };
24
+ export async function toResult(op) {
25
+ try {
26
+ const value = await op();
27
+ return { ok: true, value };
28
+ }
29
+ catch (error) {
30
+ return { ok: false, error };
31
+ }
32
+ }
33
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/camunda/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAwC,MAAM,qCAAqC,CAAC;AAErH,qFAAqF;AACrF,oEAAoE;AACpE,sFAAsF;AACtF,8EAA8E;AAC9E,qFAAqF;AACrF,kFAAkF;AAClF,4BAA4B;AAC5B,EAAE;AACF,wFAAwF;AACxF,wFAAwF;AACxF,qFAAqF;AACrF,wFAAwF;AACxF,aAAa;AAEb,IAAI,MAAsC,CAAC;AAE3C,MAAM,UAAU,SAAS;IACvB,IAAI,CAAC,MAAM;QAAE,MAAM,GAAG,wBAAwB,EAAE,CAAC;IACjD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;kFACkF;AAClF,MAAM,CAAC,MAAM,OAAO,GAAG,EAAE,WAAW,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,EAAW,CAAC;AAEnE,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAI,EAAoB;IACpD,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,EAAE,EAAE,CAAC;QACzB,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;IAC7B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;IAC9B,CAAC;AACH,CAAC"}
@@ -0,0 +1,166 @@
1
+ import { getClient, NO_WAIT } from "./client.js";
2
+ const client = () => getClient();
3
+ const PAGE_SIZE = 100;
4
+ async function paginateAll(fetchPage) {
5
+ const all = [];
6
+ let from = 0;
7
+ for (;;) {
8
+ const { items, page } = await fetchPage({ from, limit: PAGE_SIZE });
9
+ all.push(...items);
10
+ from += items.length;
11
+ if (items.length === 0 || from >= page.totalItems)
12
+ break;
13
+ }
14
+ return all;
15
+ }
16
+ export async function listAllTenants() {
17
+ const items = await paginateAll((page) => client().searchTenants({ page }, NO_WAIT));
18
+ return items.map((t) => ({ tenantId: t.tenantId, name: t.name, description: t.description }));
19
+ }
20
+ export async function listAllRoles() {
21
+ const items = await paginateAll((page) => client().searchRoles({ page }, NO_WAIT));
22
+ return items.map((r) => ({ roleId: r.roleId, name: r.name, description: r.description }));
23
+ }
24
+ export async function listAllGroups() {
25
+ const items = await paginateAll((page) => client().searchGroups({ page }, NO_WAIT));
26
+ return items.map((g) => ({ groupId: g.groupId, name: g.name, description: g.description }));
27
+ }
28
+ export async function listAllMappingRules() {
29
+ const items = await paginateAll((page) => client().searchMappingRule({ page }, NO_WAIT));
30
+ return items.map((m) => ({
31
+ mappingRuleId: m.mappingRuleId,
32
+ claimName: m.claimName,
33
+ claimValue: m.claimValue,
34
+ name: m.name,
35
+ }));
36
+ }
37
+ export async function listAllAuthorizations() {
38
+ const items = await paginateAll((page) => client().searchAuthorizations({ page }, NO_WAIT));
39
+ return items
40
+ .filter((a) => a.resourceId !== null)
41
+ .map((a) => ({
42
+ authorizationKey: a.authorizationKey,
43
+ ownerId: a.ownerId,
44
+ ownerType: a.ownerType,
45
+ resourceType: a.resourceType,
46
+ resourceId: a.resourceId,
47
+ permissionTypes: a.permissionTypes,
48
+ }));
49
+ }
50
+ async function fetchRelationships(roles, groups, tenants, onProgress) {
51
+ const roleGroup = new Set();
52
+ const roleMappingRule = new Set();
53
+ const groupMappingRule = new Set();
54
+ const tenantRole = new Set();
55
+ const tenantGroup = new Set();
56
+ const groupUser = new Set();
57
+ const groupClient = new Set();
58
+ const roleUser = new Set();
59
+ const roleClient = new Set();
60
+ const tenantMappingRule = new Set();
61
+ const total = roles.length + groups.length + tenants.length;
62
+ let completed = 0;
63
+ const tick = () => onProgress?.(++completed, total);
64
+ await Promise.all([
65
+ ...roles.map(async (role) => {
66
+ const [groupsForRole, mappingRulesForRole, usersForRole, clientsForRole] = await Promise.all([
67
+ paginateAll((page) => client().searchGroupsForRole({ roleId: role.roleId, page }, NO_WAIT)),
68
+ paginateAll((page) => client().searchMappingRulesForRole({ roleId: role.roleId, page }, NO_WAIT)),
69
+ paginateAll((page) => client().searchUsersForRole({ roleId: role.roleId, page }, NO_WAIT)),
70
+ paginateAll((page) => client().searchClientsForRole({ roleId: role.roleId, page }, NO_WAIT)),
71
+ ]);
72
+ for (const g of groupsForRole)
73
+ roleGroup.add(`${role.roleId}::${g.groupId}`);
74
+ for (const m of mappingRulesForRole)
75
+ roleMappingRule.add(`${role.roleId}::${m.mappingRuleId}`);
76
+ for (const u of usersForRole)
77
+ roleUser.add(`${role.roleId}::${u.username}`);
78
+ for (const c of clientsForRole)
79
+ roleClient.add(`${role.roleId}::${c.clientId}`);
80
+ tick();
81
+ }),
82
+ ...groups.map(async (group) => {
83
+ const [mappingRulesForGroup, usersForGroup, clientsForGroup] = await Promise.all([
84
+ paginateAll((page) => client().searchMappingRulesForGroup({ groupId: group.groupId, page }, NO_WAIT)),
85
+ paginateAll((page) => client().searchUsersForGroup({ groupId: group.groupId, page }, NO_WAIT)),
86
+ paginateAll((page) => client().searchClientsForGroup({ groupId: group.groupId, page }, NO_WAIT)),
87
+ ]);
88
+ for (const m of mappingRulesForGroup)
89
+ groupMappingRule.add(`${group.groupId}::${m.mappingRuleId}`);
90
+ for (const u of usersForGroup)
91
+ groupUser.add(`${group.groupId}::${u.username}`);
92
+ for (const c of clientsForGroup)
93
+ groupClient.add(`${group.groupId}::${c.clientId}`);
94
+ tick();
95
+ }),
96
+ ...tenants.map(async (tenant) => {
97
+ const [rolesForTenant, groupIdsForTenant, mappingRulesForTenant] = await Promise.all([
98
+ paginateAll((page) => client().searchRolesForTenant({ tenantId: tenant.tenantId, page }, NO_WAIT)),
99
+ paginateAll((page) => client().searchGroupIdsForTenant({ tenantId: tenant.tenantId, page }, NO_WAIT)),
100
+ paginateAll((page) => client().searchMappingRulesForTenant({ tenantId: tenant.tenantId, page }, NO_WAIT)),
101
+ ]);
102
+ for (const r of rolesForTenant)
103
+ tenantRole.add(`${tenant.tenantId}::${r.roleId}`);
104
+ for (const g of groupIdsForTenant)
105
+ tenantGroup.add(`${tenant.tenantId}::${g.groupId}`);
106
+ for (const m of mappingRulesForTenant)
107
+ tenantMappingRule.add(`${tenant.tenantId}::${m.mappingRuleId}`);
108
+ tick();
109
+ }),
110
+ ]);
111
+ return {
112
+ roleGroup,
113
+ roleMappingRule,
114
+ groupMappingRule,
115
+ tenantRole,
116
+ tenantGroup,
117
+ groupUser,
118
+ groupClient,
119
+ roleUser,
120
+ roleClient,
121
+ tenantMappingRule,
122
+ };
123
+ }
124
+ /**
125
+ * Fetches the complete current cluster state in one pass: every tenant, role,
126
+ * group, mapping rule and authorization, plus every relationship pair between
127
+ * them. Relationship membership is queried for every *current* entity (not just
128
+ * ones named in the desired spec) - this is what makes cascading deletes possible
129
+ * in prune mode: an entity about to be pruned still has its stale links surfaced
130
+ * here, so diff.ts can schedule the unassign/delete-authorization actions that
131
+ * must run before the entity itself is deleted.
132
+ *
133
+ * `onProgress`, if given, is called as each of the two fetch phases (entity
134
+ * lists, then per-entity relationship lookups) makes progress - purely for
135
+ * caller-side UX (e.g. a CLI progress indicator); this function itself never
136
+ * renders anything.
137
+ */
138
+ export async function fetchCurrentState(onProgress) {
139
+ let entitiesCompleted = 0;
140
+ const entityTick = () => onProgress?.({ phase: "entities", completed: ++entitiesCompleted, total: 5 });
141
+ const [tenants, roles, groups, mappingRules, authorizations] = await Promise.all([
142
+ listAllTenants().then((r) => {
143
+ entityTick();
144
+ return r;
145
+ }),
146
+ listAllRoles().then((r) => {
147
+ entityTick();
148
+ return r;
149
+ }),
150
+ listAllGroups().then((r) => {
151
+ entityTick();
152
+ return r;
153
+ }),
154
+ listAllMappingRules().then((r) => {
155
+ entityTick();
156
+ return r;
157
+ }),
158
+ listAllAuthorizations().then((r) => {
159
+ entityTick();
160
+ return r;
161
+ }),
162
+ ]);
163
+ const relationships = await fetchRelationships(roles, groups, tenants, (completed, total) => onProgress?.({ phase: "relationships", completed, total }));
164
+ return { tenants, roles, groups, mappingRules, authorizations, relationships };
165
+ }
166
+ //# sourceMappingURL=list-all.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-all.js","sourceRoot":"","sources":["../../src/camunda/list-all.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,63 @@
1
+ import { getClient, toResult } from "./client.js";
2
+ const client = () => getClient();
3
+ export const tenantOps = {
4
+ create: (tenantId, name, description) => toResult(() => client().createTenant({ tenantId, name, description })),
5
+ update: (tenantId, name, description) => toResult(() => client().updateTenant({ tenantId, name, description })),
6
+ delete: (tenantId) => toResult(() => client().deleteTenant({ tenantId })),
7
+ assignRole: (tenantId, roleId) => toResult(() => client().assignRoleToTenant({ tenantId, roleId })),
8
+ unassignRole: (tenantId, roleId) => toResult(() => client().unassignRoleFromTenant({ tenantId, roleId })),
9
+ assignGroup: (tenantId, groupId) => toResult(() => client().assignGroupToTenant({ tenantId, groupId })),
10
+ unassignGroup: (tenantId, groupId) => toResult(() => client().unassignGroupFromTenant({ tenantId, groupId })),
11
+ assignMappingRule: (tenantId, mappingRuleId) => toResult(() => client().assignMappingRuleToTenant({ tenantId, mappingRuleId })),
12
+ unassignMappingRule: (tenantId, mappingRuleId) => toResult(() => client().unassignMappingRuleFromTenant({ tenantId, mappingRuleId })),
13
+ };
14
+ export const roleOps = {
15
+ create: (roleId, name, description) => toResult(() => client().createRole({ roleId, name, description })),
16
+ update: (roleId, name, description) => toResult(() => client().updateRole({ roleId, name, description })),
17
+ delete: (roleId) => toResult(() => client().deleteRole({ roleId })),
18
+ assignGroup: (roleId, groupId) => toResult(() => client().assignRoleToGroup({ roleId, groupId })),
19
+ unassignGroup: (roleId, groupId) => toResult(() => client().unassignRoleFromGroup({ roleId, groupId })),
20
+ assignMappingRule: (roleId, mappingRuleId) => toResult(() => client().assignRoleToMappingRule({ roleId, mappingRuleId })),
21
+ unassignMappingRule: (roleId, mappingRuleId) => toResult(() => client().unassignRoleFromMappingRule({ roleId, mappingRuleId })),
22
+ assignUser: (roleId, username) => toResult(() => client().assignRoleToUser({ roleId, username })),
23
+ unassignUser: (roleId, username) => toResult(() => client().unassignRoleFromUser({ roleId, username })),
24
+ assignClient: (roleId, clientId) => toResult(() => client().assignRoleToClient({ roleId, clientId })),
25
+ unassignClient: (roleId, clientId) => toResult(() => client().unassignRoleFromClient({ roleId, clientId })),
26
+ };
27
+ export const groupOps = {
28
+ create: (groupId, name, description) => toResult(() => client().createGroup({ groupId, name, description })),
29
+ update: (groupId, name, description) => toResult(() => client().updateGroup({ groupId, name, description })),
30
+ delete: (groupId) => toResult(() => client().deleteGroup({ groupId })),
31
+ assignMappingRule: (groupId, mappingRuleId) => toResult(() => client().assignMappingRuleToGroup({ groupId, mappingRuleId })),
32
+ unassignMappingRule: (groupId, mappingRuleId) => toResult(() => client().unassignMappingRuleFromGroup({ groupId, mappingRuleId })),
33
+ assignUser: (groupId, username) => toResult(() => client().assignUserToGroup({ groupId, username })),
34
+ unassignUser: (groupId, username) => toResult(() => client().unassignUserFromGroup({ groupId, username })),
35
+ assignClient: (groupId, clientId) => toResult(() => client().assignClientToGroup({ groupId, clientId })),
36
+ unassignClient: (groupId, clientId) => toResult(() => client().unassignClientFromGroup({ groupId, clientId })),
37
+ };
38
+ export const mappingRuleOps = {
39
+ create: (mappingRuleId, claimName, claimValue, name) => toResult(() => client().createMappingRule({ mappingRuleId, claimName, claimValue, name })),
40
+ update: (mappingRuleId, claimName, claimValue, name) => toResult(() => client().updateMappingRule({ mappingRuleId, claimName, claimValue, name })),
41
+ delete: (mappingRuleId) => toResult(() => client().deleteMappingRule({ mappingRuleId })),
42
+ };
43
+ export const authorizationOps = {
44
+ create: (auth) => toResult(() => client().createAuthorization({
45
+ ownerId: auth.ownerId,
46
+ ownerType: auth.ownerType,
47
+ resourceId: auth.resourceId,
48
+ resourceType: auth.resourceType,
49
+ permissionTypes: auth.permissions,
50
+ })),
51
+ // updateAuthorization is a full replace, never a partial patch - always send the
52
+ // complete desired shape.
53
+ update: (authorizationKey, auth) => toResult(() => client().updateAuthorization({
54
+ authorizationKey,
55
+ ownerId: auth.ownerId,
56
+ ownerType: auth.ownerType,
57
+ resourceId: auth.resourceId,
58
+ resourceType: auth.resourceType,
59
+ permissionTypes: auth.permissions,
60
+ })),
61
+ delete: (authorizationKey) => toResult(() => client().deleteAuthorization({ authorizationKey })),
62
+ };
63
+ //# sourceMappingURL=ops.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ops.js","sourceRoot":"","sources":["../../src/camunda/ops.ts"],"names":[],"mappings":"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"}
package/dist/cli.js ADDED
@@ -0,0 +1,140 @@
1
+ #!/usr/bin/env node
2
+ import { createInterface } from "node:readline/promises";
3
+ import { Command } from "commander";
4
+ import { loadSpec, SpecValidationError } from "./spec/load.js";
5
+ import { fetchCurrentState } from "./camunda/list-all.js";
6
+ import { buildPlan } from "./reconcile/diff.js";
7
+ import { applyPlan } from "./reconcile/apply.js";
8
+ import { formatApplyResult, formatPlan } from "./reconcile/format.js";
9
+ import { createProgressReporter } from "./progress.js";
10
+ // Load ./.env into process.env (if present) so CAMUNDA_* vars work without the
11
+ // operator having to `export` each line by hand. Silently ignored when there's
12
+ // no .env file - real env vars (e.g. injected by CI) still take precedence
13
+ // wherever they're already set, since loadEnvFile does not override existing vars.
14
+ try {
15
+ process.loadEnvFile();
16
+ }
17
+ catch (err) {
18
+ if (err.code !== "ENOENT")
19
+ throw err;
20
+ }
21
+ function reportError(err) {
22
+ const message = err instanceof SpecValidationError || err instanceof Error ? err.message : String(err);
23
+ console.error(message);
24
+ const cause = err instanceof Error ? err.cause : undefined;
25
+ if (cause) {
26
+ console.error(`Caused by: ${cause instanceof Error ? cause.message : String(cause)}`);
27
+ }
28
+ if (message === "fetch failed") {
29
+ console.error("Hint: check that CAMUNDA_REST_ADDRESS/CAMUNDA_OAUTH_URL/CAMUNDA_CLIENT_ID/CAMUNDA_CLIENT_SECRET are set (via .env or the environment) and reachable.");
30
+ }
31
+ }
32
+ async function fetchCurrentStateWithProgress() {
33
+ const progress = createProgressReporter();
34
+ try {
35
+ const current = await fetchCurrentState((e) => {
36
+ progress.update(e.phase === "entities"
37
+ ? `Fetching entities… (${e.completed}/${e.total})`
38
+ : `Resolving relationships… (${e.completed}/${e.total})`);
39
+ });
40
+ progress.stop(`Fetched current cluster state: ${current.tenants.length} tenants, ${current.roles.length} roles, ${current.groups.length} groups, ${current.mappingRules.length} mapping rules, ${current.authorizations.length} authorizations.`);
41
+ return current;
42
+ }
43
+ finally {
44
+ progress.stop();
45
+ }
46
+ }
47
+ const program = new Command();
48
+ program.name("camunda-idac").description("Identity-as-code reconciler for Camunda 8 (tenants, roles, groups, mapping rules, authorizations)");
49
+ program
50
+ .command("validate")
51
+ .description("validate the spec's schema and referential integrity - no network access")
52
+ .argument("<spec>", "path to the YAML spec file")
53
+ .action(async (specPath) => {
54
+ try {
55
+ await loadSpec(specPath);
56
+ console.log("Spec is valid.");
57
+ }
58
+ catch (err) {
59
+ reportError(err);
60
+ process.exitCode = 1;
61
+ }
62
+ });
63
+ program
64
+ .command("plan")
65
+ .description("show what would change against the live cluster, without applying anything")
66
+ .argument("<spec>", "path to the YAML spec file")
67
+ .option("--prune", "also compute deletions for anything not in the spec", false)
68
+ .option("--show-protected", "also list actions blocked by the admin/default safety guard", false)
69
+ .action(async (specPath, opts) => {
70
+ try {
71
+ const spec = await loadSpec(specPath);
72
+ const current = await fetchCurrentStateWithProgress();
73
+ const mode = opts.prune ? "prune" : "additive";
74
+ const plan = buildPlan(spec, current, mode);
75
+ console.log(formatPlan(plan, { showProtected: opts.showProtected }));
76
+ // Mirrors `terraform plan -detailed-exitcode`: 0 = no drift, 1 = drift found (or
77
+ // an unresolved mapping-rule claim conflict, which needs a spec change either way).
78
+ process.exitCode = plan.actions.length > 0 || plan.conflicts.length > 0 ? 1 : 0;
79
+ }
80
+ catch (err) {
81
+ reportError(err);
82
+ process.exitCode = 1;
83
+ }
84
+ });
85
+ program
86
+ .command("apply")
87
+ .description("apply the spec to the live cluster")
88
+ .argument("<spec>", "path to the YAML spec file")
89
+ .option("--prune", "also delete anything not in the spec", false)
90
+ .option("--yes", "skip the interactive confirmation prompt", false)
91
+ .option("--show-protected", "also list actions blocked by the admin/default safety guard", false)
92
+ .action(async (specPath, opts) => {
93
+ try {
94
+ const spec = await loadSpec(specPath);
95
+ const current = await fetchCurrentStateWithProgress();
96
+ const mode = opts.prune ? "prune" : "additive";
97
+ const plan = buildPlan(spec, current, mode);
98
+ console.log(formatPlan(plan, { showProtected: opts.showProtected }));
99
+ if (plan.actions.length === 0) {
100
+ process.exitCode = plan.conflicts.length > 0 ? 1 : 0;
101
+ return;
102
+ }
103
+ if (!opts.yes) {
104
+ if (!process.stdin.isTTY) {
105
+ console.error("\nRefusing to apply without --yes in a non-interactive shell.");
106
+ process.exitCode = 1;
107
+ return;
108
+ }
109
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
110
+ const suffix = mode === "prune" ? " (including deletions)" : "";
111
+ const answer = await rl.question(`\nApply ${plan.actions.length} action(s)${suffix}? [y/N] `);
112
+ rl.close();
113
+ if (!/^y(es)?$/i.test(answer.trim())) {
114
+ console.log("Aborted.");
115
+ return;
116
+ }
117
+ }
118
+ const applyProgress = createProgressReporter();
119
+ let result;
120
+ try {
121
+ result = await applyPlan(plan, (e) => {
122
+ if (e.type === "start") {
123
+ applyProgress.update(`[${e.index + 1}/${e.total}] ${e.action.description}`);
124
+ }
125
+ });
126
+ }
127
+ finally {
128
+ applyProgress.stop();
129
+ }
130
+ console.log("");
131
+ console.log(formatApplyResult(result, { showProtected: opts.showProtected }));
132
+ process.exitCode = result.failed.length > 0 || plan.conflicts.length > 0 ? 1 : 0;
133
+ }
134
+ catch (err) {
135
+ reportError(err);
136
+ process.exitCode = 1;
137
+ }
138
+ });
139
+ await program.parseAsync(process.argv);
140
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
package/dist/colors.js ADDED
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Minimal ANSI color helpers for CLI output. Disabled automatically when
3
+ * stdout isn't a TTY (piped/redirected output, CI logs) or when `NO_COLOR`
4
+ * is set, per https://no-color.org - checked per call (not cached at import)
5
+ * so it always reflects the current stream.
6
+ */
7
+ function colorEnabled() {
8
+ return process.stdout.isTTY === true && !process.env.NO_COLOR;
9
+ }
10
+ function wrap(code, text) {
11
+ return colorEnabled() ? `\x1b[${code}m${text}\x1b[0m` : text;
12
+ }
13
+ export const red = (text) => wrap("31", text);
14
+ export const green = (text) => wrap("32", text);
15
+ export const yellow = (text) => wrap("33", text);
16
+ export const cyan = (text) => wrap("36", text);
17
+ export const dim = (text) => wrap("2", text);
18
+ export const bold = (text) => wrap("1", text);
19
+ //# sourceMappingURL=colors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"colors.js","sourceRoot":"","sources":["../src/colors.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,SAAS,YAAY;IACnB,OAAO,OAAO,CAAC,MAAM,CAAC,KAAK,KAAK,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC;AAChE,CAAC;AAED,SAAS,IAAI,CAAC,IAAY,EAAE,IAAY;IACtC,OAAO,YAAY,EAAE,CAAC,CAAC,CAAC,QAAQ,IAAI,IAAI,IAAI,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;AAC/D,CAAC;AAED,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC,IAAY,EAAU,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AAC9D,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,IAAY,EAAU,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AAChE,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,IAAY,EAAU,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AACjE,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,IAAY,EAAU,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AAC/D,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC,IAAY,EAAU,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;AAC7D,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,IAAY,EAAU,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC"}