@wtfalch/foundry 0.5.0 → 0.7.1
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/dist/bootstrap/bootstrap.d.ts +16 -1
- package/dist/bootstrap/bootstrap.js +40 -2
- package/dist/bootstrap/declare.d.ts +3 -1
- package/dist/bootstrap/declare.js +12 -3
- package/dist/bootstrap/versions.d.ts +17 -0
- package/dist/bootstrap/versions.js +12 -0
- package/dist/calls-sfu-deploy-support.d.ts +8 -0
- package/dist/calls-sfu-deploy-support.js +10 -1
- package/dist/calls-sfu.d.ts +36 -12
- package/dist/calls-sfu.js +42 -9
- package/dist/index.d.ts +10 -4
- package/dist/index.js +6 -3
- package/dist/migrations/0019_mail_owner_mailbox.sql +15 -0
- package/dist/migrations/0020_mail_apps.sql +7 -0
- package/dist/migrations/0021_mail_role_mailboxes.sql +6 -0
- package/dist/migrations/0022_chat_enabled.sql +6 -0
- package/dist/migrations/0023_hosting_app_env.sql +8 -0
- package/dist/migrations/0024_audit_events.sql +211 -0
- package/dist/migrations/0025_audit_display.sql +147 -0
- package/dist/migrations/0026_audit_erase_email_guard.sql +78 -0
- package/dist/migrations/0027_audit_chain.sql +170 -0
- package/dist/migrations/0028_audit_rls.sql +111 -0
- package/dist/org.d.ts +105 -0
- package/dist/org.js +101 -0
- package/dist/plan/agora.d.ts +21 -0
- package/dist/plan/agora.js +23 -0
- package/dist/plan/calls-matrix.d.ts +2 -2
- package/dist/plan/calls-matrix.js +3 -2
- package/dist/plan/cloudflared-connector.d.ts +3 -2
- package/dist/plan/cloudflared-connector.js +5 -3
- package/dist/plan/diff.d.ts +15 -2
- package/dist/plan/diff.js +399 -51
- package/dist/plan/executor.d.ts +307 -61
- package/dist/plan/executor.js +489 -129
- package/dist/plan/index.d.ts +9 -1
- package/dist/plan/index.js +5 -1
- package/dist/plan/login-host.d.ts +64 -0
- package/dist/plan/login-host.js +52 -0
- package/dist/plan/mail-copy.d.ts +125 -0
- package/dist/plan/mail-copy.js +166 -0
- package/dist/plan/mail-identity-allowlist.d.ts +50 -0
- package/dist/plan/mail-identity-allowlist.js +11 -0
- package/dist/plan/mail-identity.d.ts +68 -0
- package/dist/plan/mail-identity.js +17 -0
- package/dist/plan/plan-apply.d.ts +26 -8
- package/dist/plan/plan-apply.js +10 -9
- package/dist/plan/platform-diff.d.ts +207 -10
- package/dist/plan/platform-diff.js +403 -15
- package/dist/plan/platform-org.d.ts +3 -2
- package/dist/plan/platform-providers.d.ts +139 -25
- package/dist/plan/platform-providers.js +1531 -95
- package/dist/plan/platform-sfu.d.ts +54 -19
- package/dist/plan/platform-sfu.js +64 -22
- package/dist/plan/providers-readers.js +44 -1
- package/dist/plan/zitadel-machine-user.d.ts +60 -11
- package/dist/plan/zitadel-machine-user.js +182 -39
- package/dist/requested-changes.d.ts +17 -7
- package/dist/requested-changes.js +37 -7
- package/dist/store/audit.d.ts +40 -4
- package/dist/store/audit.js +114 -29
- package/dist/store/postgres.js +35 -3
- package/dist/store/schema.d.ts +109 -1
- package/dist/store/schema.js +20 -0
- package/dist/store.d.ts +7 -0
- package/package.json +5 -3
- package/versions.json +8 -0
|
@@ -17,14 +17,19 @@ export interface AuditActor {
|
|
|
17
17
|
/**
|
|
18
18
|
* The seam onto `@wtfalch/audit`.
|
|
19
19
|
*
|
|
20
|
-
* #19
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
20
|
+
* #19 asked for `@wtfalch/audit` itself, but at the time that package's
|
|
21
|
+
* `record`/`ledger` were bound to one app's Drizzle table, session model and
|
|
22
|
+
* closed `EventName`/`ActorClass` vocabulary -- none of which foundry's SDK
|
|
23
|
+
* package had. This interface was the stand-in, logged as a Finding on #19
|
|
24
|
+
* rather than a half adoption.
|
|
25
|
+
*
|
|
26
|
+
* #232: `@wtfalch/audit` now supports a service with no tenant database of
|
|
27
|
+
* its own (`ledgerVocabulary`, `tenantId: null`, the org as `target`) -- see
|
|
28
|
+
* `store/audit.ts`'s `createPostgresAuditLog`, which binds `ledger.sign` to
|
|
29
|
+
* foundry's own closed vocabulary and `foundry_audit_events`' replacement,
|
|
30
|
+
* `audit_events` (`@wtfalch/audit`'s own table, through migrations
|
|
31
|
+
* 0022-0026). This interface itself is unchanged -- `bootstrap.ts` and
|
|
32
|
+
* `redactingAudit` need no change either.
|
|
28
33
|
*/
|
|
29
34
|
export interface AuditLog {
|
|
30
35
|
recordPlan(entry: {
|
|
@@ -178,6 +183,10 @@ export interface PlatformStepExecutor {
|
|
|
178
183
|
*/
|
|
179
184
|
blockedSteps?(platform: DeclaredPlatform, recordedIds: Readonly<Record<string, string>>): Promise<{
|
|
180
185
|
auth?: string;
|
|
186
|
+
/** #211 round 6: see `PlanPlatformOptions.blocked.authExecutorMissing`. */
|
|
187
|
+
authExecutorMissing?: boolean;
|
|
188
|
+
/** #216 round 5: see `PlanPlatformOptions.blocked.authOtherInputsMissing`. */
|
|
189
|
+
authOtherInputsMissing?: string[];
|
|
181
190
|
files?: string;
|
|
182
191
|
integrations?: string;
|
|
183
192
|
ai?: string;
|
|
@@ -190,6 +199,7 @@ export interface PlatformStepExecutor {
|
|
|
190
199
|
*/
|
|
191
200
|
driftedSteps?(platform: DeclaredPlatform, recordedIds: Readonly<Record<string, string>>): Promise<{
|
|
192
201
|
archon?: boolean;
|
|
202
|
+
auth?: boolean;
|
|
193
203
|
}>;
|
|
194
204
|
execute(action: StepAction, context: PlatformStepExecutionContext): Promise<{
|
|
195
205
|
resourceId?: string;
|
|
@@ -276,6 +286,13 @@ export interface FoundryPlanApplyOptions {
|
|
|
276
286
|
* step never runs (and fails) where no scheduler is deployed.
|
|
277
287
|
*/
|
|
278
288
|
jobsScheduler?: boolean;
|
|
289
|
+
/**
|
|
290
|
+
* #267: true when the host's executor was built with a `loginHostBindings`
|
|
291
|
+
* port. Optional, and false without it: each org's login host is then
|
|
292
|
+
* reported blocked instead of planned, so nothing is trusted or repointed
|
|
293
|
+
* before zitadel-login's binding can be written.
|
|
294
|
+
*/
|
|
295
|
+
loginHostBindings?: boolean;
|
|
279
296
|
/**
|
|
280
297
|
* #177: true when the host's executor was built with its own `filesOrganisation`
|
|
281
298
|
* / `aiOrganisation` port. Without one, the org step needs the platform's
|
|
@@ -329,6 +346,7 @@ export declare class FoundryPlanApply implements PlanApply {
|
|
|
329
346
|
private readonly actor;
|
|
330
347
|
private readonly agora;
|
|
331
348
|
private readonly jobsScheduler;
|
|
349
|
+
private readonly loginHostBindings;
|
|
332
350
|
private readonly hostFiles;
|
|
333
351
|
private readonly hostAi;
|
|
334
352
|
private readonly now;
|
package/dist/plan/plan-apply.js
CHANGED
|
@@ -78,6 +78,7 @@ export class FoundryPlanApply {
|
|
|
78
78
|
actor;
|
|
79
79
|
agora;
|
|
80
80
|
jobsScheduler;
|
|
81
|
+
loginHostBindings;
|
|
81
82
|
hostFiles;
|
|
82
83
|
hostAi;
|
|
83
84
|
now;
|
|
@@ -92,6 +93,7 @@ export class FoundryPlanApply {
|
|
|
92
93
|
this.actor = options.actor;
|
|
93
94
|
this.agora = options.agora;
|
|
94
95
|
this.jobsScheduler = options.jobsScheduler ?? false;
|
|
96
|
+
this.loginHostBindings = options.loginHostBindings ?? false;
|
|
95
97
|
this.hostFiles = options.filesOrganisation ?? false;
|
|
96
98
|
this.hostAi = options.aiOrganisation ?? false;
|
|
97
99
|
this.now = options.now ?? (() => new Date());
|
|
@@ -351,7 +353,7 @@ export class FoundryPlanApply {
|
|
|
351
353
|
this.orgPlatformReadiness(),
|
|
352
354
|
this.orgAgoraHost(id),
|
|
353
355
|
]);
|
|
354
|
-
const detail = computePlanDetail(org, live, applied?.serviceIds ?? {}, agoraHost, this.jobsScheduler, platformReadiness);
|
|
356
|
+
const detail = computePlanDetail(org, live, applied?.serviceIds ?? {}, agoraHost, this.jobsScheduler, platformReadiness, { loginHostBindings: this.loginHostBindings });
|
|
355
357
|
return { org, plan: toPlan(detail), detail };
|
|
356
358
|
}
|
|
357
359
|
/**
|
|
@@ -617,12 +619,13 @@ function stepField(action) {
|
|
|
617
619
|
*
|
|
618
620
|
* Three sources, in this order:
|
|
619
621
|
* - fields no planner step exists for yet, so no apply can make them true:
|
|
620
|
-
* SSO, guests and solo when turned on,
|
|
621
|
-
*
|
|
622
|
-
*
|
|
623
|
-
*
|
|
624
|
-
*
|
|
625
|
-
*
|
|
622
|
+
* SSO, guests and solo when turned on, an adopted app in the `repo` form
|
|
623
|
+
* (#7's `#15` comment: "declared but refused by `apply`"), and calls or
|
|
624
|
+
* hosting on a domain the org has not recorded (#145: calls on the org's
|
|
625
|
+
* own domain now has a planner step, the same way hosting's own domain
|
|
626
|
+
* does, so it only fails for that one missing-domain reason, not
|
|
627
|
+
* unconditionally). `bespokeAppRepo` is not one of these: `coolify:app`
|
|
628
|
+
* reads it (#240), so it converges with that step like any other field;
|
|
626
629
|
* - chat's reverse re-key, which the planner surfaces but which is not built
|
|
627
630
|
* (#7 amendment 3), so it counts as failed even when no step threw;
|
|
628
631
|
* - on a failed apply, the field of every planned step from the one that
|
|
@@ -646,8 +649,6 @@ function failedFields(org, detail, completed, serviceIds) {
|
|
|
646
649
|
failed.add('guests.enabled');
|
|
647
650
|
if (org.solo.enabled)
|
|
648
651
|
failed.add('solo.enabled');
|
|
649
|
-
if (org.bespokeAppRepo !== null)
|
|
650
|
-
failed.add('bespokeAppRepo');
|
|
651
652
|
if (org.adoptedApp?.form === 'repo')
|
|
652
653
|
failed.add('adoptedApp');
|
|
653
654
|
// `planCallsService`/`planTunnel`/`planZone` all share this same domain
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { OrgId } from '../org.js';
|
|
1
|
+
import type { DeclaredOrg, OrgId } from '../org.js';
|
|
2
2
|
import type { Plan, UnmanagedItem } from '../plan.js';
|
|
3
3
|
import type { DeclaredPlatform } from '../platform.js';
|
|
4
4
|
import type { PlannedStep } from './diff.js';
|
|
@@ -55,6 +55,17 @@ export declare const PLATFORM_ARCHON_KEY = "platform:archon";
|
|
|
55
55
|
*/
|
|
56
56
|
export declare const PLATFORM_ARCHON_APPLIED_HOSTNAME_SCOPE_KEY = "archon_applied_hostname";
|
|
57
57
|
export declare const PLATFORM_ARCHON_APPLIED_GIT_REF_SCOPE_KEY = "archon_applied_git_ref";
|
|
58
|
+
/**
|
|
59
|
+
* #211 round 4: the broker app id Archon last registered its entry with.
|
|
60
|
+
* `provisionPlatformArchon` reads the broker to register with from
|
|
61
|
+
* {@link PLATFORM_AUTH_BROKER_SCOPE_KEY} alone, so a broker recreated under a
|
|
62
|
+
* new app id (the old one deleted by hand, or `platform:auth` minting a fresh
|
|
63
|
+
* one) leaves Archon "applied" against a broker that no longer holds its
|
|
64
|
+
* entry. `planArchon` plans the step again whenever this differs from the
|
|
65
|
+
* currently recorded {@link PLATFORM_AUTH_BROKER_SCOPE_KEY}, the same way a
|
|
66
|
+
* changed hostname or `gitRef` does.
|
|
67
|
+
*/
|
|
68
|
+
export declare const PLATFORM_ARCHON_APPLIED_BROKER_SCOPE_KEY = "archon_applied_broker_app";
|
|
58
69
|
/**
|
|
59
70
|
* #175: set to '1' before the step points the tunnel at `http_status:404`
|
|
60
71
|
* (Access app rebuild), cleared to '' once the real ingress is written back.
|
|
@@ -64,6 +75,121 @@ export declare const PLATFORM_ARCHON_APPLIED_GIT_REF_SCOPE_KEY = "archon_applied
|
|
|
64
75
|
export declare const PLATFORM_ARCHON_GATE_CLOSED_SCOPE_KEY = "archon_gate_closed";
|
|
65
76
|
export declare const PLATFORM_AUTH_ADMIN_USER_SCOPE_KEY = "zitadel_platform_admin_user_id";
|
|
66
77
|
export declare const PLATFORM_AUTH_ADMIN_UNDELIVERED_SCOPE_KEY = "zitadel_platform_admin_user_undelivered";
|
|
78
|
+
/**
|
|
79
|
+
* #216 (building on #209/#215): the `IAM_LOGIN_CLIENT` machine user minted
|
|
80
|
+
* for the login app and the broker, mirroring
|
|
81
|
+
* {@link PLATFORM_AUTH_ADMIN_USER_SCOPE_KEY}/
|
|
82
|
+
* {@link PLATFORM_AUTH_ADMIN_UNDELIVERED_SCOPE_KEY} in shape -- a recorded
|
|
83
|
+
* id once delivered, an undelivered id recorded first, the moment the user
|
|
84
|
+
* is minted.
|
|
85
|
+
*
|
|
86
|
+
* Unlike the admin pair, an undelivered login-client key never blocks
|
|
87
|
+
* {@link planAuth} from planning the step again -- #216 round 2: `planAuth`
|
|
88
|
+
* below does read it, but only to surface a non-blocking note (alongside a
|
|
89
|
+
* planned step, the way #211 round 3's broker-deploy block already is)
|
|
90
|
+
* rather than to hold the step back. Revoking a stale login-client PAT
|
|
91
|
+
* destroys nothing -- unlike the admin user's, whose loss the admin pair's
|
|
92
|
+
* own "delete that user by hand" message exists for because nothing else
|
|
93
|
+
* here re-derives the ZITADEL masterkey a lost admin PAT might have been the
|
|
94
|
+
* only record of -- so `mintLoginClientMachineUser` (`zitadel-machine-user.ts`)
|
|
95
|
+
* always lists and deletes every PAT the user already holds before minting a
|
|
96
|
+
* fresh one. That is what lets `provisionPlatformAuth` simply re-mint on the
|
|
97
|
+
* next run, with no manual step, which is #216's whole fix for the bug PR
|
|
98
|
+
* #215 shipped with: PR #215 mirrored the admin pair's forever-blocking
|
|
99
|
+
* behaviour for this key too, which meant one failed Coolify call lost the
|
|
100
|
+
* login-client token for good.
|
|
101
|
+
*
|
|
102
|
+
* #216 round 4: the value recorded here is JSON ({@link
|
|
103
|
+
* PlatformAuthLoginClientRecord}, parsed back by
|
|
104
|
+
* {@link parseLoginClientRecord}), not the bare user id round 2-3 wrote --
|
|
105
|
+
* the user id alone can never tell a healthy delivery from one a concurrent
|
|
106
|
+
* apply has since clobbered, because `mintLoginClientMachineUser` reuses the
|
|
107
|
+
* same user on every mint. The PAT id travels alongside it so {@link
|
|
108
|
+
* planAuth} can ask ZITADEL, on every plan, whether that exact PAT is still
|
|
109
|
+
* the sole live one.
|
|
110
|
+
*
|
|
111
|
+
* #216 round 5: that alone is still not enough -- a recorded PAT can be the
|
|
112
|
+
* sole live one in ZITADEL while Coolify holds a *different*, already-dead
|
|
113
|
+
* token, when two concurrent applies interleave their own writes and
|
|
114
|
+
* records in the right (wrong) order (see `authLoginClientDrifted`'s own
|
|
115
|
+
* doc comment in `platform-providers.ts` for the exact ordering). So the
|
|
116
|
+
* record also carries `tokenHash`, a sha256 of the exact token that was
|
|
117
|
+
* delivered -- never the token itself -- which `authLoginClientDrifted`
|
|
118
|
+
* compares against what is actually live in both apps' Coolify envs.
|
|
119
|
+
*/
|
|
120
|
+
export declare const PLATFORM_AUTH_LOGIN_CLIENT_USER_SCOPE_KEY = "zitadel_platform_login_client_user_id";
|
|
121
|
+
export declare const PLATFORM_AUTH_LOGIN_CLIENT_UNDELIVERED_SCOPE_KEY = "zitadel_platform_login_client_user_undelivered";
|
|
122
|
+
/**
|
|
123
|
+
* #216 round 4/5: what {@link PLATFORM_AUTH_LOGIN_CLIENT_USER_SCOPE_KEY}
|
|
124
|
+
* records once delivery succeeds -- the minted machine user's id, the exact
|
|
125
|
+
* PAT id that was handed to the login app and the broker, and (round 5) a
|
|
126
|
+
* sha256 of the exact token value, never the value itself.
|
|
127
|
+
*/
|
|
128
|
+
export interface PlatformAuthLoginClientRecord {
|
|
129
|
+
readonly userId: string;
|
|
130
|
+
readonly patId: string;
|
|
131
|
+
readonly tokenHash: string;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Parses a {@link PLATFORM_AUTH_LOGIN_CLIENT_USER_SCOPE_KEY} scope id back
|
|
135
|
+
* into a {@link PlatformAuthLoginClientRecord}. `null` for anything that is
|
|
136
|
+
* not one -- absent, the pre-round-4 plain user-id string, the round 2-4
|
|
137
|
+
* `{userId, patId}` shape with no `tokenHash`, or corrupt JSON -- the same
|
|
138
|
+
* "malformed reads as unapplied, never throws" rule
|
|
139
|
+
* {@link parseBrokerDeployRecord} follows and for the same reason: this is a
|
|
140
|
+
* planning read, not a validation boundary. A pre-round-5 record reading as
|
|
141
|
+
* unapplied is the intended migration: the next apply's fresh mint recomputes
|
|
142
|
+
* it in the new shape, the same way a pre-round-4 plain-string record already
|
|
143
|
+
* did.
|
|
144
|
+
*/
|
|
145
|
+
export declare function parseLoginClientRecord(raw: string | undefined): PlatformAuthLoginClientRecord | null;
|
|
146
|
+
/**
|
|
147
|
+
* #204/#211: the sign-in broker app `provisionPlatformAuth` creates alongside
|
|
148
|
+
* ZITADEL and the login app. Defined here, not in `platform-providers.ts`
|
|
149
|
+
* (which imports it), because `planAuth` below needs it too -- a recorded
|
|
150
|
+
* `coolify:app:platform:auth` key with no recorded broker id is a platform
|
|
151
|
+
* provisioned before #204 shipped, and must still plan the step again so the
|
|
152
|
+
* broker gets created rather than being read as fully applied.
|
|
153
|
+
*/
|
|
154
|
+
export declare const PLATFORM_AUTH_BROKER_SCOPE_KEY = "coolify_platform_auth_broker_app";
|
|
155
|
+
/**
|
|
156
|
+
* #211: recorded once the broker has actually been deployed -- distinct from
|
|
157
|
+
* {@link PLATFORM_AUTH_BROKER_SCOPE_KEY} (the app exists) precisely because
|
|
158
|
+
* the app can exist for a while before it is ever deployed (see
|
|
159
|
+
* `missingBrokerInputs` in `platform-providers.ts`). Defined here, not there,
|
|
160
|
+
* for the same reason as {@link PLATFORM_AUTH_BROKER_SCOPE_KEY}: `planAuth`
|
|
161
|
+
* below needs it too, so a broker that is created but not yet deployed still
|
|
162
|
+
* plans the step again instead of reading as fully applied for good.
|
|
163
|
+
*/
|
|
164
|
+
export declare const PLATFORM_AUTH_BROKER_DEPLOYED_SCOPE_KEY = "coolify_platform_auth_broker_deployed";
|
|
165
|
+
/**
|
|
166
|
+
* #211 round 5: what {@link PLATFORM_AUTH_BROKER_DEPLOYED_SCOPE_KEY} records
|
|
167
|
+
* once a deploy succeeds -- the broker app id that was deployed, and a sha256
|
|
168
|
+
* of the exact `AUTH_APPS` value that was live at that deploy, never the
|
|
169
|
+
* value itself (`platform-providers.ts`'s `hashAuthApps`: a secret must never
|
|
170
|
+
* reach a recorded scope id). Round 2-4 recorded a plain broker-id string
|
|
171
|
+
* there, which could only ever mean "deployed at least once" -- it could not
|
|
172
|
+
* tell a broker recreated under a new app id, or a crash between writing
|
|
173
|
+
* `AUTH_APPS` and deploying, from one still fully applied. This record is
|
|
174
|
+
* what lets `brokerDeployNeeded` (`platform-providers.ts`) and {@link planAuth}
|
|
175
|
+
* below answer both, from one mechanism instead of two ad hoc booleans.
|
|
176
|
+
*/
|
|
177
|
+
export interface BrokerDeployRecord {
|
|
178
|
+
readonly brokerAppId: string;
|
|
179
|
+
readonly authAppsHash: string;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Parses a {@link PLATFORM_AUTH_BROKER_DEPLOYED_SCOPE_KEY} scope id back into
|
|
183
|
+
* a {@link BrokerDeployRecord}. `null` for anything that is not one --
|
|
184
|
+
* absent, the pre-round-5 plain broker-id string, or corrupt JSON -- because
|
|
185
|
+
* this is a planning read, not a validation boundary: a malformed record
|
|
186
|
+
* must read as "not deployed" so the step plans (and overwrites it) again,
|
|
187
|
+
* never throw and take the rest of the plan down with it. Exported here
|
|
188
|
+
* rather than defined in `platform-providers.ts` for the same reason
|
|
189
|
+
* {@link PLATFORM_AUTH_BROKER_DEPLOYED_SCOPE_KEY} itself was moved here in
|
|
190
|
+
* round 2 -- {@link planAuth} below needs it too, without a circular import.
|
|
191
|
+
*/
|
|
192
|
+
export declare function parseBrokerDeployRecord(raw: string | undefined): BrokerDeployRecord | null;
|
|
67
193
|
/**
|
|
68
194
|
* #197: the `cloudflared` connector app `provisionPlatformAuth` runs for its
|
|
69
195
|
* own tunnel. Consulted by `planAuth` below so that a tunnel recorded with no
|
|
@@ -76,6 +202,21 @@ export declare const PLATFORM_AUTH_CONNECTOR_APP_SCOPE_KEY = "coolify_platform_a
|
|
|
76
202
|
export declare const PLATFORM_MAIL_CONNECTOR_APP_SCOPE_KEY = "coolify_platform_mail_connector_app";
|
|
77
203
|
/** #197: the same connector scope id for the Archon step's own tunnel, read by `planArchon`. */
|
|
78
204
|
export declare const PLATFORM_ARCHON_CONNECTOR_APP_SCOPE_KEY = "coolify_platform_archon_connector_app";
|
|
205
|
+
/**
|
|
206
|
+
* #213: the three held-key refs, under tenant `platform`, Archon's own
|
|
207
|
+
* onboarding reads before it can start (archon#101 round 3, archon#104).
|
|
208
|
+
* `planArchon`'s step puts each one, once, before Archon's app deploys; an
|
|
209
|
+
* entry already held is left alone, never overwritten
|
|
210
|
+
* (`putArchonMasterKeys` in `platform-providers.ts`). The Coolify URL and
|
|
211
|
+
* token are values this package already deploys with; the Cloudflare
|
|
212
|
+
* parent token ("API Tokens Write", so Archon can mint its own scoped
|
|
213
|
+
* child tokens from it) is a human-created credential the host supplies --
|
|
214
|
+
* neither Coolify nor Cloudflare lets either be minted over an API (#213
|
|
215
|
+
* "Human steps").
|
|
216
|
+
*/
|
|
217
|
+
export declare const PLATFORM_ARCHON_MASTER_COOLIFY_URL_REF = "platform:master:coolify-url";
|
|
218
|
+
export declare const PLATFORM_ARCHON_MASTER_COOLIFY_TOKEN_REF = "platform:master:coolify-token";
|
|
219
|
+
export declare const PLATFORM_ARCHON_MASTER_CLOUDFLARE_TOKEN_REF = "platform:master:cloudflare-token";
|
|
79
220
|
/**
|
|
80
221
|
* #169: `platform:<service>` for the platform's own mail server (Stalwart),
|
|
81
222
|
* mirroring {@link PLATFORM_AUTH_KEY} exactly.
|
|
@@ -127,6 +268,28 @@ export declare function platformMailMxHost(apex: string): string;
|
|
|
127
268
|
*/
|
|
128
269
|
export declare const ORG_MAIL_APPLIED_APEX_SCOPE_KEY = "mail_applied_apex";
|
|
129
270
|
export declare const ORG_MAIL_APPLIED_HOST_SCOPE_KEY = "mail_applied_host";
|
|
271
|
+
/**
|
|
272
|
+
* #243: the org's `hosting.appEnv` values the last `coolify:app` apply pushed,
|
|
273
|
+
* recorded as one JSON object (env name to value; ids and a domain, never a
|
|
274
|
+
* secret). `planApp` plans the step again when {@link resolveAppEnv} differs
|
|
275
|
+
* from it, so a changed map reaches an app that is already live.
|
|
276
|
+
*/
|
|
277
|
+
export declare const APP_ENV_APPLIED_SCOPE_KEY = "app_env_applied";
|
|
278
|
+
/**
|
|
279
|
+
* #239: set to '1' once an app has been restarted after its database URLs
|
|
280
|
+
* were pushed. Not a URL. Without it a crash between the push and the restart
|
|
281
|
+
* would leave a stale container that no plan notices.
|
|
282
|
+
*/
|
|
283
|
+
export declare const DB_ENV_APPLIED_SCOPE_KEY = "db_env_applied";
|
|
284
|
+
/**
|
|
285
|
+
* The `hosting.appEnv` entries whose source has a recorded value, in env-name
|
|
286
|
+
* order, and the env names whose source has none yet. Shared by `planApp` and
|
|
287
|
+
* the executor's `pushAppEnv` so both read the same recorded ids.
|
|
288
|
+
*/
|
|
289
|
+
export declare function resolveAppEnv(org: DeclaredOrg, recorded: Readonly<Record<string, string>>): {
|
|
290
|
+
values: Record<string, string>;
|
|
291
|
+
unresolved: Array<[string, string]>;
|
|
292
|
+
};
|
|
130
293
|
/**
|
|
131
294
|
* #172: the resource key `planAi` plans under and `FoundryPlatformStepExecutor`
|
|
132
295
|
* dispatches on, the same `platform:<service>` shape as
|
|
@@ -150,6 +313,27 @@ export declare const PLATFORM_AI_INTERNAL_URL_SCOPE_KEY = "ai_platform_internal_
|
|
|
150
313
|
*/
|
|
151
314
|
export declare const PLATFORM_AI_MANAGEMENT_KEY_SCOPE_KEY = "ai_platform_management_key_id";
|
|
152
315
|
export declare const PLATFORM_AI_MANAGEMENT_KEY_UNDELIVERED_SCOPE_KEY = "ai_platform_management_key_undelivered";
|
|
316
|
+
/**
|
|
317
|
+
* #201: set when ai's `POST /v1/platform/keys` reports its `archon` key
|
|
318
|
+
* already exists but returns no secret -- a mint this record never learned
|
|
319
|
+
* about (most likely the crash window {@link PLATFORM_AI_MANAGEMENT_KEY_UNDELIVERED_SCOPE_KEY}'s
|
|
320
|
+
* own comment describes: the secret returned once and was never recorded).
|
|
321
|
+
* ai shows a credential's secret only at mint time, so it cannot be
|
|
322
|
+
* recovered; the planner reports this instead of minting under another
|
|
323
|
+
* name. A person revokes the live `archon` key in ai and removes this
|
|
324
|
+
* recorded key to let the step mint a fresh one.
|
|
325
|
+
*/
|
|
326
|
+
export declare const PLATFORM_AI_MANAGEMENT_KEY_CONFLICT_SCOPE_KEY = "ai_platform_management_key_conflict";
|
|
327
|
+
/**
|
|
328
|
+
* #201: the same two-key discipline as {@link PLATFORM_INTEGRATIONS_KEY_UNDELIVERED_SCOPE_KEY}
|
|
329
|
+
* and {@link PLATFORM_INTEGRATIONS_KEY_SET_SCOPE_KEY}, for the Ed25519 pair
|
|
330
|
+
* foundry mints to sign its calls to ai's `POST /v1/platform/keys`. The
|
|
331
|
+
* undelivered key is recorded the moment the pair is minted; the set key,
|
|
332
|
+
* only once the private half was delivered and the public half pinned on
|
|
333
|
+
* the runner as `MANAGEMENT_PUBLIC_KEYS`.
|
|
334
|
+
*/
|
|
335
|
+
export declare const PLATFORM_AI_SIGNING_KEY_UNDELIVERED_SCOPE_KEY = "ai_platform_signing_key_undelivered";
|
|
336
|
+
export declare const PLATFORM_AI_SIGNING_KEY_SET_SCOPE_KEY = "ai_platform_signing_key_set";
|
|
153
337
|
/**
|
|
154
338
|
* #172: ai's platform (operator) tenant id, which the management key belongs
|
|
155
339
|
* to -- what ai's own README calls `AI_ORGANISATION_ID`. Not a secret.
|
|
@@ -175,14 +359,6 @@ export declare const PLATFORM_AI_MIGRATE_BLOCKED_SCOPE_KEY = "ai_platform_migrat
|
|
|
175
359
|
* that throws) is repaired by the next one.
|
|
176
360
|
*/
|
|
177
361
|
export declare const PLATFORM_AI_DEPLOY_PENDING_SCOPE_KEY = "ai_platform_deploy_pending";
|
|
178
|
-
/**
|
|
179
|
-
* #172: what the planner says while no AI management key minter is supplied.
|
|
180
|
-
* A fixed text: it is part of the stale-plan comparison. ai issues its first
|
|
181
|
-
* platform credential only through its `keys:issue-archon` script, run
|
|
182
|
-
* against its database with its keys worker credential; it has no HTTP route
|
|
183
|
-
* for that, so foundry cannot build a minter over ai's admin API yet.
|
|
184
|
-
*/
|
|
185
|
-
export declare const PLATFORM_AI_MINTER_BLOCKED = "the platform's AI host is blocked, not planned: no AI management key minter was supplied. ai mints its first platform key only through its keys:issue-archon script against its database, so the host must supply PlatformAiDeps.managementKeyMinter";
|
|
186
362
|
/**
|
|
187
363
|
* #171: the resource key `planFiles` plans under and `FoundryPlatformStepExecutor`
|
|
188
364
|
* dispatches on, the {@link PLATFORM_AUTH_KEY} shape for the files host.
|
|
@@ -243,6 +419,23 @@ export interface PlanPlatformOptions {
|
|
|
243
419
|
/** Per-step block reasons the executor reports (default `{}`). */
|
|
244
420
|
blocked?: {
|
|
245
421
|
auth?: string;
|
|
422
|
+
/**
|
|
423
|
+
* #211 round 6: set once the auth block is "the host built the platform
|
|
424
|
+
* executor without its auth dependencies" -- distinct from `auth` itself,
|
|
425
|
+
* which also covers "the broker exists but cannot deploy yet" (#209/#210
|
|
426
|
+
* still pending). `planAuth` must withhold the step for the former
|
|
427
|
+
* whatever the recorded ids say; it must not for the latter.
|
|
428
|
+
*/
|
|
429
|
+
authExecutorMissing?: boolean;
|
|
430
|
+
/**
|
|
431
|
+
* #216 round 5: the broker's required inputs other than
|
|
432
|
+
* `ZITADEL_SERVICE_USER_TOKEN` that are still missing (a subset of what
|
|
433
|
+
* `auth`'s own text already names, filtered) -- {@link planAuth} reads
|
|
434
|
+
* this to say, accurately, whether a needed login-client re-mint can
|
|
435
|
+
* actually happen on the next apply or is itself waiting on one of
|
|
436
|
+
* these. Default `[]`.
|
|
437
|
+
*/
|
|
438
|
+
authOtherInputsMissing?: string[];
|
|
246
439
|
files?: string;
|
|
247
440
|
integrations?: string;
|
|
248
441
|
ai?: string;
|
|
@@ -252,10 +445,14 @@ export interface PlanPlatformOptions {
|
|
|
252
445
|
/**
|
|
253
446
|
* Steps whose live state differs from the declared one in a way the recorded
|
|
254
447
|
* ids cannot show (default `{}`). `archon`: the Cloudflare Access policy's
|
|
255
|
-
* include list is not the declared one.
|
|
448
|
+
* include list is not the declared one. `auth` (#216 round 4): the
|
|
449
|
+
* login-client PAT recorded under
|
|
450
|
+
* {@link PLATFORM_AUTH_LOGIN_CLIENT_USER_SCOPE_KEY} is no longer the sole
|
|
451
|
+
* live PAT on that ZITADEL machine user.
|
|
256
452
|
*/
|
|
257
453
|
drifted?: {
|
|
258
454
|
archon?: boolean;
|
|
455
|
+
auth?: boolean;
|
|
259
456
|
};
|
|
260
457
|
}
|
|
261
458
|
/**
|