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 +21 -0
- package/README.md +117 -0
- package/dist/camunda/client.js +33 -0
- package/dist/camunda/client.js.map +1 -0
- package/dist/camunda/list-all.js +166 -0
- package/dist/camunda/list-all.js.map +1 -0
- package/dist/camunda/ops.js +63 -0
- package/dist/camunda/ops.js.map +1 -0
- package/dist/cli.js +140 -0
- package/dist/cli.js.map +1 -0
- package/dist/colors.js +19 -0
- package/dist/colors.js.map +1 -0
- package/dist/progress.js +67 -0
- package/dist/progress.js.map +1 -0
- package/dist/reconcile/apply.js +31 -0
- package/dist/reconcile/apply.js.map +1 -0
- package/dist/reconcile/diff.js +280 -0
- package/dist/reconcile/diff.js.map +1 -0
- package/dist/reconcile/format.js +92 -0
- package/dist/reconcile/format.js.map +1 -0
- package/dist/reconcile/order.js +58 -0
- package/dist/reconcile/order.js.map +1 -0
- package/dist/reconcile/protect.js +78 -0
- package/dist/reconcile/protect.js.map +1 -0
- package/dist/reconcile/types.js +18 -0
- package/dist/reconcile/types.js.map +1 -0
- package/dist/spec/load.js +46 -0
- package/dist/spec/load.js.map +1 -0
- package/dist/spec/schema.js +274 -0
- package/dist/spec/schema.js.map +1 -0
- package/package.json +53 -0
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
|
package/dist/cli.js.map
ADDED
|
@@ -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"}
|