@homeflare/alchemy 0.48.0 → 0.49.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/README.md +11 -0
- package/dist/cloudflare/cloudflared-tunnel-api.d.ts +87 -0
- package/dist/cloudflare/cloudflared-tunnel-api.d.ts.map +1 -0
- package/dist/cloudflare/cloudflared-tunnel-form.d.ts +49 -0
- package/dist/cloudflare/cloudflared-tunnel-form.d.ts.map +1 -0
- package/dist/cloudflare/cloudflared-tunnel-harness.d.ts +45 -0
- package/dist/cloudflare/cloudflared-tunnel-harness.d.ts.map +1 -0
- package/dist/cloudflare/cloudflared-tunnel-lifecycle.d.ts +21 -0
- package/dist/cloudflare/cloudflared-tunnel-lifecycle.d.ts.map +1 -0
- package/dist/cloudflare/cloudflared-tunnel.d.ts +39 -0
- package/dist/cloudflare/cloudflared-tunnel.d.ts.map +1 -0
- package/dist/cloudflare/fake-access.d.ts +40 -0
- package/dist/cloudflare/fake-access.d.ts.map +1 -0
- package/dist/cloudflare/fake-mesh.d.ts +7 -2
- package/dist/cloudflare/fake-mesh.d.ts.map +1 -1
- package/dist/cloudflare/fake-tunnel.d.ts +48 -0
- package/dist/cloudflare/fake-tunnel.d.ts.map +1 -0
- package/dist/cloudflare/index.d.ts +15 -4
- package/dist/cloudflare/index.d.ts.map +1 -1
- package/dist/cloudflare/index.js +518 -7
- package/dist/cloudflare/index.js.map +15 -4
- package/dist/cloudflare/providers.d.ts +1 -1
- package/dist/cloudflare/providers.d.ts.map +1 -1
- package/dist/cloudflare/saas-oidc-api.d.ts +88 -0
- package/dist/cloudflare/saas-oidc-api.d.ts.map +1 -0
- package/dist/cloudflare/saas-oidc-consumer.d.ts +22 -0
- package/dist/cloudflare/saas-oidc-consumer.d.ts.map +1 -0
- package/dist/cloudflare/saas-oidc-error.d.ts +22 -0
- package/dist/cloudflare/saas-oidc-error.d.ts.map +1 -0
- package/dist/cloudflare/saas-oidc-form.d.ts +48 -0
- package/dist/cloudflare/saas-oidc-form.d.ts.map +1 -0
- package/dist/cloudflare/saas-oidc-harness.d.ts +50 -0
- package/dist/cloudflare/saas-oidc-harness.d.ts.map +1 -0
- package/dist/cloudflare/saas-oidc-lifecycle.d.ts +14 -0
- package/dist/cloudflare/saas-oidc-lifecycle.d.ts.map +1 -0
- package/dist/cloudflare/saas-oidc-props.d.ts +139 -0
- package/dist/cloudflare/saas-oidc-props.d.ts.map +1 -0
- package/dist/cloudflare/saas-oidc-team.d.ts +9 -0
- package/dist/cloudflare/saas-oidc-team.d.ts.map +1 -0
- package/dist/cloudflare/saas-oidc-wire.d.ts +58 -0
- package/dist/cloudflare/saas-oidc-wire.d.ts.map +1 -0
- package/dist/cloudflare/saas-oidc.d.ts +36 -0
- package/dist/cloudflare/saas-oidc.d.ts.map +1 -0
- package/dist/talos/cluster-adapter-errors.d.ts.map +1 -1
- package/dist/talos/cluster-adapter.d.ts +2 -1
- package/dist/talos/cluster-adapter.d.ts.map +1 -1
- package/dist/talos/index.js +19 -8
- package/dist/talos/index.js.map +6 -6
- package/dist/talos/mint-temp-file.d.ts.map +1 -1
- package/dist/talos/talosctl.d.ts +29 -0
- package/dist/talos/talosctl.d.ts.map +1 -1
- package/docs/cloudflared-tunnel.md +136 -0
- package/docs/credentials.md +1 -1
- package/docs/ownership.md +3 -2
- package/docs/saas-oidc.md +185 -0
- package/docs/talos-openbao-adapter.md +3 -2
- package/docs/upstream-conformance-families.md +1 -1
- package/docs/upstream-conformance.md +3 -0
- package/package.json +1 -1
- package/src/cloudflare/cloudflared-tunnel-api.ts +150 -0
- package/src/cloudflare/cloudflared-tunnel-edges.test.ts +179 -0
- package/src/cloudflare/cloudflared-tunnel-form.ts +78 -0
- package/src/cloudflare/cloudflared-tunnel-harness.ts +126 -0
- package/src/cloudflare/cloudflared-tunnel-lifecycle.ts +146 -0
- package/src/cloudflare/cloudflared-tunnel-state.test.ts +104 -0
- package/src/cloudflare/cloudflared-tunnel.test.ts +164 -0
- package/src/cloudflare/cloudflared-tunnel.ts +116 -0
- package/src/cloudflare/fake-access.ts +196 -0
- package/src/cloudflare/fake-mesh.ts +6 -3
- package/src/cloudflare/fake-tunnel.ts +148 -0
- package/src/cloudflare/index.ts +27 -4
- package/src/cloudflare/providers.ts +16 -3
- package/src/cloudflare/saas-oidc-api.ts +224 -0
- package/src/cloudflare/saas-oidc-consumer.ts +35 -0
- package/src/cloudflare/saas-oidc-error.ts +52 -0
- package/src/cloudflare/saas-oidc-form.test.ts +227 -0
- package/src/cloudflare/saas-oidc-form.ts +190 -0
- package/src/cloudflare/saas-oidc-harness.ts +140 -0
- package/src/cloudflare/saas-oidc-lifecycle.ts +150 -0
- package/src/cloudflare/saas-oidc-parse-error.test.ts +180 -0
- package/src/cloudflare/saas-oidc-props.ts +147 -0
- package/src/cloudflare/saas-oidc-read.test.ts +85 -0
- package/src/cloudflare/saas-oidc-stable.test.ts +38 -0
- package/src/cloudflare/saas-oidc-state.test.ts +128 -0
- package/src/cloudflare/saas-oidc-team.test.ts +88 -0
- package/src/cloudflare/saas-oidc-team.ts +70 -0
- package/src/cloudflare/saas-oidc-wire.ts +116 -0
- package/src/cloudflare/saas-oidc.test.ts +201 -0
- package/src/cloudflare/saas-oidc.ts +107 -0
- package/src/talos/cluster-adapter-errors.ts +2 -1
- package/src/talos/cluster-adapter-move.test.ts +2 -0
- package/src/talos/cluster-adapter.ts +2 -1
- package/src/talos/mint-temp-file.test.ts +44 -0
- package/src/talos/mint-temp-file.ts +16 -4
- package/src/talos/talosctl-probe-kill.test.ts +56 -0
- package/src/talos/talosctl.test.ts +54 -1
- package/src/talos/talosctl.ts +34 -2
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `HomeFlare.Access.SaasOidcApplication` — the pure helpers the lifecycle uses: validation, the
|
|
3
|
+
* issuer URLs, drift, the write body and the attribute mapping. The props and attributes types are
|
|
4
|
+
* declared in saas-oidc-props.ts and re-exported here.
|
|
5
|
+
*
|
|
6
|
+
* ⛔ THE ATTRIBUTES NEVER HOLD THE CLIENT SECRET, and nothing here can: `ObservedApp`
|
|
7
|
+
* (saas-oidc-api.ts) has no field for it. A client that authenticates with PKCE alone declares
|
|
8
|
+
* `allowPkceWithoutClientSecret: true`, and then no secret exists to keep.
|
|
9
|
+
* ★ THE ISSUER IS `https://<teamDomain>/cdn-cgi/access/sso/oidc/<clientId>`. The team domain is a
|
|
10
|
+
* prop; the openbao copy this came from hardcoded one account's. Cloudflare also reports the
|
|
11
|
+
* same host in the app's own `domain` field (Alchemy's `Access.Application` doc: for `saas`
|
|
12
|
+
* "Cloudflare uses the OIDC issuer"), and `checkTeam` refuses a declaration that disagrees with it.
|
|
13
|
+
*/
|
|
14
|
+
import { SaasOidcError } from './saas-oidc-error.ts';
|
|
15
|
+
import type { SaasOidcApplicationAttributes, SaasOidcApplicationProps } from './saas-oidc-props.ts';
|
|
16
|
+
import type { AppWrite, ObservedApp } from './saas-oidc-wire.ts';
|
|
17
|
+
export type { OidcGrantType, OidcScope, SaasOidcApplicationAttributes, SaasOidcApplicationProps, } from './saas-oidc-props.ts';
|
|
18
|
+
/** ⛔ Fail closed on a declaration the API would accept but nobody meant. */
|
|
19
|
+
export declare const validateSaasOidc: (props: SaasOidcApplicationProps) => SaasOidcError | undefined;
|
|
20
|
+
export declare const issuerFor: (teamDomain: string, clientId: string) => string;
|
|
21
|
+
/**
|
|
22
|
+
* ⛔ A DECLARED TEAM DOMAIN THAT DISAGREES WITH THE APP'S OWN `domain` is refused: the issuer in
|
|
23
|
+
* the attributes would point at a different team than the one that holds the app.
|
|
24
|
+
* ⛔ WHEN CLOUDFLARE REPORTS NO `domain` there is nothing to compare, so the team the row already
|
|
25
|
+
* recorded (`knownTeam`, from state) stands in: a declaration that moves it is refused, because
|
|
26
|
+
* `issuer` is a declared stable and must not move under the row. With no `knownTeam` either
|
|
27
|
+
* (a first create or a cold adoption) there is nothing to compare against and the declaration
|
|
28
|
+
* stands.
|
|
29
|
+
*/
|
|
30
|
+
export declare const checkTeam: (teamDomain: string, app: ObservedApp, knownTeam?: string) => SaasOidcError | undefined;
|
|
31
|
+
/** The request body for a create or an update. */
|
|
32
|
+
export declare const writeBody: (news: SaasOidcApplicationProps, name: string) => AppWrite;
|
|
33
|
+
/**
|
|
34
|
+
* Does the live app differ from the declaration? Compared: name, auth type, redirect URIs, scopes,
|
|
35
|
+
* grant types (each as a set), both lifetimes, the PKCE flag and the policies IN ORDER — the
|
|
36
|
+
* openbao copy's set plus the policy order, kept so adopting a live app is not newly a write.
|
|
37
|
+
* ⚠️ NOT COMPARED: `sessionDuration`, `allowedIdps`, `autoRedirectToIdentity`, `appLauncherVisible`,
|
|
38
|
+
* `appLauncherUrl`. They are written on create and on any sync, but a change to only those does
|
|
39
|
+
* not trigger one. Carried over unchanged; see saas-oidc.md.
|
|
40
|
+
*/
|
|
41
|
+
export declare const needsSync: (news: SaasOidcApplicationProps, observed: ObservedApp, name: string) => boolean;
|
|
42
|
+
/**
|
|
43
|
+
* The attributes of a live app, or `undefined` when it lacks an id, an `aud` or a client id (so it
|
|
44
|
+
* is not a SaaS OIDC app this package can describe). `teamDomain` is the declared one, or, for a
|
|
45
|
+
* read that has no declaration (state written before the prop existed), the host Cloudflare reports.
|
|
46
|
+
*/
|
|
47
|
+
export declare const toAttributes: (app: ObservedApp, accountId: string, fallbackName: string, declaredTeam: string | undefined) => SaasOidcApplicationAttributes | undefined;
|
|
48
|
+
//# sourceMappingURL=saas-oidc-form.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"saas-oidc-form.d.ts","sourceRoot":"","sources":["../../src/cloudflare/saas-oidc-form.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,6BAA6B,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AACpG,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAIjE,YAAY,EACV,aAAa,EACb,SAAS,EACT,6BAA6B,EAC7B,wBAAwB,GACzB,MAAM,sBAAsB,CAAC;AAI9B,4EAA4E;AAC5E,eAAO,MAAM,gBAAgB,UAAW,wBAAwB,KAAG,aAAa,GAAG,SAmBlF,CAAC;AAEF,eAAO,MAAM,SAAS,eAAgB,MAAM,YAAY,MAAM,KAAG,MACJ,CAAC;AAI9D;;;;;;;;GAQG;AACH,eAAO,MAAM,SAAS,eACR,MAAM,OACb,WAAW,cACJ,MAAM,KACjB,aAAa,GAAG,SAalB,CAAC;AAKF,kDAAkD;AAClD,eAAO,MAAM,SAAS,SAAU,wBAAwB,QAAQ,MAAM,KAAG,QAmBvE,CAAC;AAgBH;;;;;;;GAOG;AACH,eAAO,MAAM,SAAS,SACd,wBAAwB,YACpB,WAAW,QACf,MAAM,KACX,OAcF,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,YAAY,QAClB,WAAW,aACL,MAAM,gBACH,MAAM,gBACN,MAAM,GAAG,SAAS,KAC/B,6BAA6B,GAAG,SA6BlC,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import * as State from 'alchemy/State';
|
|
2
|
+
import * as Effect from 'effect/Effect';
|
|
3
|
+
import * as Exit from 'effect/Exit';
|
|
4
|
+
import * as Layer from 'effect/Layer';
|
|
5
|
+
import { type FakeAccess } from './fake-access.ts';
|
|
6
|
+
import type { SaasOidcApplicationAttributes, SaasOidcApplicationProps } from './saas-oidc-form.ts';
|
|
7
|
+
import { SaasOidcApplication } from './saas-oidc.ts';
|
|
8
|
+
export declare const strict: <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>;
|
|
9
|
+
export declare const ids: {
|
|
10
|
+
fqn: string;
|
|
11
|
+
id: string;
|
|
12
|
+
instanceId: string;
|
|
13
|
+
};
|
|
14
|
+
export declare const extra: {
|
|
15
|
+
bindings: never;
|
|
16
|
+
session: never;
|
|
17
|
+
};
|
|
18
|
+
export type P = Effect.Success<typeof SaasOidcApplication.Provider>;
|
|
19
|
+
/** A public PKCE client, the shape Headlamp declares (Q6). */
|
|
20
|
+
export declare const publicClient: (over?: Partial<SaasOidcApplicationProps>) => SaasOidcApplicationProps;
|
|
21
|
+
/** The wire `saas_app` of a live app that matches `publicClient()` exactly (no drift to sync). */
|
|
22
|
+
export declare const LIVE_OIDC: {
|
|
23
|
+
auth_type: string;
|
|
24
|
+
redirect_uris: string[];
|
|
25
|
+
scopes: string[];
|
|
26
|
+
grant_types: string[];
|
|
27
|
+
access_token_lifetime: string;
|
|
28
|
+
allow_pkce_without_client_secret: boolean;
|
|
29
|
+
};
|
|
30
|
+
/** Build the provider over the fake and hand it to `use`. */
|
|
31
|
+
export declare const run: <A, E>(fake: FakeAccess, use: (p: P) => Effect.Effect<A, E, never>) => Promise<A>;
|
|
32
|
+
export declare const reconcile: (p: P, news: SaasOidcApplicationProps, output?: SaasOidcApplicationAttributes) => Effect.Effect<SaasOidcApplicationAttributes, any, never>;
|
|
33
|
+
export declare const read: (p: P, olds: SaasOidcApplicationProps, output?: SaasOidcApplicationAttributes) => Effect.Effect<SaasOidcApplicationAttributes | undefined, any, never>;
|
|
34
|
+
/** The writes the fake saw, in order: `['POST', 'PUT', …]`. */
|
|
35
|
+
export declare const writes: (fake: FakeAccess) => string[];
|
|
36
|
+
type Rows = Record<string, Record<string, Record<string, State.ResourceState>>>;
|
|
37
|
+
/**
|
|
38
|
+
* ★ THE REAL ENGINE, NOT A MODEL OF IT: `Plan.make` + `apply` over an in-memory state store, as
|
|
39
|
+
* mesh-node-harness.ts does. `rows` is that store, so a test can serialise exactly what Alchemy
|
|
40
|
+
* would persist.
|
|
41
|
+
*/
|
|
42
|
+
export declare const engine: (fake: FakeAccess, extra?: Layer.Layer<never, never, never>) => {
|
|
43
|
+
deploy: <A, E, R>(declare: Effect.Effect<A, E, R>) => Promise<Exit.Exit<unknown, unknown>>;
|
|
44
|
+
rows: Rows;
|
|
45
|
+
status: (fqn: string) => "created" | "creating" | "deleting" | "replaced" | "replacing" | "updated" | "updating" | undefined;
|
|
46
|
+
};
|
|
47
|
+
/** The failure sentence of a deploy, or `''` when it succeeded. */
|
|
48
|
+
export declare const failureOf: (exit: Exit.Exit<unknown, unknown>) => string;
|
|
49
|
+
export {};
|
|
50
|
+
//# sourceMappingURL=saas-oidc-harness.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"saas-oidc-harness.d.ts","sourceRoot":"","sources":["../../src/cloudflare/saas-oidc-harness.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,KAAK,MAAM,eAAe,CAAC;AAGvC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,IAAI,MAAM,aAAa,CAAC;AACpC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAEtC,OAAO,EAAE,KAAK,UAAU,EAAQ,MAAM,kBAAkB,CAAC;AAEzD,OAAO,KAAK,EAAE,6BAA6B,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AACnG,OAAO,EAAE,mBAAmB,EAA+B,MAAM,gBAAgB,CAAC;AAclF,eAAO,MAAM,MAAM,GAAI,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAAG,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CACpB,CAAC;AAEnE,eAAO,MAAM,GAAG;IAAK,GAAG;IAAoB,EAAE;IAAc,UAAU;CAAS,CAAC;AAChF,eAAO,MAAM,KAAK;IAAK,QAAQ,EAAQ,KAAK;IAAE,OAAO,EAAe,KAAK;CAAE,CAAC;AAE5E,MAAM,MAAM,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,mBAAmB,CAAC,QAAQ,CAAC,CAAC;AAEpE,8DAA8D;AAC9D,eAAO,MAAM,YAAY,UACjB,OAAO,CAAC,wBAAwB,CAAC,KACtC,wBAaD,CAAC;AAEH,kGAAkG;AAClG,eAAO,MAAM,SAAS;IACpB,SAAS;IACT,aAAa;IACb,MAAM;IACN,WAAW;IACX,qBAAqB;IACrB,gCAAgC;CACjC,CAAC;AAEF,6DAA6D;AAC7D,eAAO,MAAM,GAAG,GAAI,CAAC,EAAE,CAAC,QAAQ,UAAU,OAAO,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,eAWlF,CAAC;AAEJ,eAAO,MAAM,SAAS,MACjB,CAAC,QACE,wBAAwB,WACrB,6BAA6B,6DAC6B,CAAC;AAEtE,eAAO,MAAM,IAAI,MACZ,CAAC,QACE,wBAAwB,WACrB,6BAA6B,yEAKvC,CAAC;AAEF,+DAA+D;AAC/D,eAAO,MAAM,MAAM,SAAU,UAAU,aAC2B,CAAC;AAEnE,KAAK,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;AAEhF;;;;GAIG;AACH,eAAO,MAAM,MAAM,SAAU,UAAU,UAAS,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;aAO9D,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;;kBAexC,MAAM;CAEvB,CAAC;AAEF,mEAAmE;AACnE,eAAO,MAAM,SAAS,SAAU,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,WACG,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import * as Effect from 'effect/Effect';
|
|
2
|
+
import { SaasOidcError } from './saas-oidc-error.ts';
|
|
3
|
+
import { type SaasOidcApplicationAttributes, type SaasOidcApplicationProps } from './saas-oidc-form.ts';
|
|
4
|
+
/**
|
|
5
|
+
* Owned: refresh by the stored id ONLY (gone is `undefined`, never a same-named app). Cold: find the app by `applicationId` or exact name and hand it
|
|
6
|
+
* back `Unowned`, so Alchemy refuses to take it over until the stack says `adopt(true)`.
|
|
7
|
+
* ★ `olds` MAY PREDATE `teamDomain` (state written by the openbao copy of this resource): the host
|
|
8
|
+
* Cloudflare reports for the app stands in, so the first plan after the move can still read.
|
|
9
|
+
*/
|
|
10
|
+
export declare const readSaasOidc: (accountId: string, id: string, olds: SaasOidcApplicationProps | undefined, output: SaasOidcApplicationAttributes | undefined) => Effect.Effect<SaasOidcApplicationAttributes | undefined, import("@distilled.cloud/cloudflare/zero-trust").AccessReferenceNotFound | import("@distilled.cloud/cloudflare/Errors").CloudflareError | import("@distilled.cloud/cloudflare/Errors").CloudflareHttpError | import("@distilled.cloud/cloudflare/Errors").CloudflareRateLimited | import("effect/http/HttpClientError").HttpClientError | import("@distilled.cloud/cloudflare/Errors").InvalidRoute | SaasOidcError | import("@distilled.cloud/cloudflare/Errors").UnknownCloudflareError | import("@distilled.cloud/cloudflare/Credentials").CredentialsError | import("@distilled.cloud/grafana").DefaultErrors, import("alchemy").InstanceId | import("alchemy").Stack | import("alchemy").Stage | import("@distilled.cloud/cloudflare/Protocol").CloudflareOpContext>;
|
|
11
|
+
/** observe, ensure (create or sync), read back. A no-op when nothing drifted. */
|
|
12
|
+
export declare const reconcileSaasOidc: (accountId: string, id: string, news: SaasOidcApplicationProps, output: SaasOidcApplicationAttributes | undefined) => Effect.Effect<SaasOidcApplicationAttributes, import("@distilled.cloud/cloudflare/zero-trust").AccessDestinationConflict | import("@distilled.cloud/cloudflare/zero-trust").AccessReferenceNotFound | import("@distilled.cloud/cloudflare/Errors").CloudflareError | import("@distilled.cloud/cloudflare/Errors").CloudflareHttpError | import("@distilled.cloud/cloudflare/Errors").CloudflareRateLimited | import("@distilled.cloud/caddy").ConfigError | import("effect/http/HttpClientError").HttpClientError | import("@distilled.cloud/cloudflare/Errors").InvalidRoute | import("@distilled.cloud/cloudflare/Credentials").OAuthRefreshError | import("@distilled.cloud/cloudflare/zero-trust").OrganizationNotFound | SaasOidcError | import("@distilled.cloud/cloudflare/Errors").UnknownCloudflareError | import("@distilled.cloud/grafana").DefaultErrors, import("alchemy").InstanceId | import("alchemy").Stack | import("alchemy").Stage | import("@distilled.cloud/cloudflare/Protocol").CloudflareOpContext>;
|
|
13
|
+
export declare const deleteSaasOidc: (output: SaasOidcApplicationAttributes) => Effect.Effect<void, import("@distilled.cloud/cloudflare/Errors").CloudflareError | import("@distilled.cloud/cloudflare/Errors").CloudflareHttpError | import("@distilled.cloud/cloudflare/Errors").CloudflareRateLimited | import("@distilled.cloud/caddy").ConfigError | import("effect/http/HttpClientError").HttpClientError | import("@distilled.cloud/cloudflare/Errors").InvalidRoute | import("@distilled.cloud/cloudflare/Credentials").OAuthRefreshError | SaasOidcError | import("@distilled.cloud/cloudflare/Errors").UnknownCloudflareError | import("@distilled.cloud/grafana").DefaultErrors, import("@distilled.cloud/cloudflare/Protocol").CloudflareOpContext>;
|
|
14
|
+
//# sourceMappingURL=saas-oidc-lifecycle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"saas-oidc-lifecycle.d.ts","sourceRoot":"","sources":["../../src/cloudflare/saas-oidc-lifecycle.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAExC,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EACL,KAAK,6BAA6B,EAClC,KAAK,wBAAwB,EAM9B,MAAM,qBAAqB,CAAC;AAqC7B;;;;;GAKG;AACH,eAAO,MAAM,YAAY,cACZ,MAAM,MACb,MAAM,QACJ,wBAAwB,GAAG,SAAS,UAClC,6BAA6B,GAAG,SAAS,uyBAiB/C,CAAC;AASL,iFAAiF;AACjF,eAAO,MAAM,iBAAiB,cACjB,MAAM,MACb,MAAM,QACJ,wBAAwB,UACtB,6BAA6B,GAAG,SAAS,g+BAmD/C,CAAC;AAEL,eAAO,MAAM,cAAc,WAAY,6BAA6B,opBACjB,CAAC"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The declared shape of `HomeFlare.Access.SaasOidcApplication` and what it reports back, apart from
|
|
3
|
+
* the pure helpers that use them (saas-oidc-form.ts re-exports both types, so imports keep working).
|
|
4
|
+
*
|
|
5
|
+
* ★ EVERY PROP FIELD CARRIES A JSDOC (provider standard S5). Where the wording below is the API's,
|
|
6
|
+
* it is the SDK's own field doc on the request type
|
|
7
|
+
* (`@distilled.cloud/cloudflare@1.0.0-rc.13` `zero-trust` `CreateAccessApplicationForAccountRequest`
|
|
8
|
+
* and `AccessApplicationsCreateRequestSaasAppOIDCSaaSApp`, src/services/zero_trust.ts:9025-9053 and
|
|
9
|
+
* :9728-9794), so a reader gets the vendor's meaning without leaving the editor.
|
|
10
|
+
* ⛔ THE ATTRIBUTES NEVER HOLD THE CLIENT SECRET, and nothing here can: there is no field for it.
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* An OIDC flow Access can serve for the client: the five literals the SDK names
|
|
14
|
+
* (`AccessApplicationsCreateRequestSaasAppOIDCSaaSAppGrantTypesItem`, zero_trust.ts:8946-8951).
|
|
15
|
+
*/
|
|
16
|
+
export type OidcGrantType = 'authorization_code' | 'authorization_code_with_pkce' | 'refresh_tokens' | 'hybrid' | 'implicit';
|
|
17
|
+
/** The user information the client may request from Access. */
|
|
18
|
+
export type OidcScope = 'openid' | 'email' | 'profile' | 'groups';
|
|
19
|
+
export interface SaasOidcApplicationProps {
|
|
20
|
+
/**
|
|
21
|
+
* Live Access application UUID. Set this when adopting a SaaS app that already exists. Without
|
|
22
|
+
* it the app is found by exact `name` among saas apps, which also works but refuses two matches.
|
|
23
|
+
*/
|
|
24
|
+
readonly applicationId?: string;
|
|
25
|
+
/** The app's name. Defaults to a physical name derived from the logical id. */
|
|
26
|
+
readonly name?: string;
|
|
27
|
+
/**
|
|
28
|
+
* The Zero Trust team domain the issuer lives on, a bare hostname such as
|
|
29
|
+
* `example.cloudflareaccess.com`: no scheme, no path. Not read from the environment, so the
|
|
30
|
+
* issuer in the attributes is the one the declaration says.
|
|
31
|
+
*/
|
|
32
|
+
readonly teamDomain: string;
|
|
33
|
+
/**
|
|
34
|
+
* How long Access sessions for this app last, in the API's duration format (`300ms` or `2h45m`).
|
|
35
|
+
* Written on create and on any sync; not drift-checked.
|
|
36
|
+
* @default '24h'
|
|
37
|
+
*/
|
|
38
|
+
readonly sessionDuration?: string;
|
|
39
|
+
/**
|
|
40
|
+
* Ids of the identity providers users may pick for this app. Written on create and on any sync;
|
|
41
|
+
* not drift-checked.
|
|
42
|
+
* @default every IdP configured in the account (the field is left out of the write)
|
|
43
|
+
*/
|
|
44
|
+
readonly allowedIdps?: ReadonlyArray<string>;
|
|
45
|
+
/**
|
|
46
|
+
* `true` makes users skip the identity-provider selection step; the API requires exactly one
|
|
47
|
+
* entry in `allowedIdps` then. Written on create and on any sync; not drift-checked.
|
|
48
|
+
* @default left out of the write (the API's default)
|
|
49
|
+
*/
|
|
50
|
+
readonly autoRedirectToIdentity?: boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Show the app in the App Launcher. Written on create and on any sync; not drift-checked.
|
|
53
|
+
* @default false
|
|
54
|
+
*/
|
|
55
|
+
readonly appLauncherVisible?: boolean;
|
|
56
|
+
/**
|
|
57
|
+
* Ids of reusable Access policies, in ascending order of precedence (the SDK's own wording:
|
|
58
|
+
* zero_trust.ts:9774). The ORDER is part of the declaration: a reorder is drift and is synced.
|
|
59
|
+
*/
|
|
60
|
+
readonly policies: ReadonlyArray<string>;
|
|
61
|
+
/** The OIDC client: the `saas_app` object of the Access application. */
|
|
62
|
+
readonly saasApp: {
|
|
63
|
+
/** The authentication protocol of the SaaS app. Only `oidc` is supported by this resource. */
|
|
64
|
+
readonly authType: 'oidc';
|
|
65
|
+
/**
|
|
66
|
+
* The permitted URLs for Cloudflare to return authorization codes and tokens to. Compared as
|
|
67
|
+
* a set (order is not significant to the API).
|
|
68
|
+
*/
|
|
69
|
+
readonly redirectUris: ReadonlyArray<string>;
|
|
70
|
+
/** The user information shared with the client. Compared as a set. */
|
|
71
|
+
readonly scopes: ReadonlyArray<OidcScope>;
|
|
72
|
+
/** The OIDC flows the client may use. Compared as a set. */
|
|
73
|
+
readonly grantTypes: ReadonlyArray<OidcGrantType>;
|
|
74
|
+
/** Lifetime of the access token after creation: `m` or `h` units, `1m` to `24h` (the SDK field doc). */
|
|
75
|
+
readonly accessTokenLifetime: string;
|
|
76
|
+
/**
|
|
77
|
+
* How long a refresh token is valid after creation: `m`, `h` or `d` units, longer than `1m`
|
|
78
|
+
* (the SDK field doc). Needed for the `refresh_tokens` grant. Sent as `refreshTokenOptions.lifetime`.
|
|
79
|
+
* @default left out of the write
|
|
80
|
+
*/
|
|
81
|
+
readonly refreshTokenLifetime?: string;
|
|
82
|
+
/**
|
|
83
|
+
* `true` makes this a PUBLIC client: the token endpoint does not require a client secret when
|
|
84
|
+
* the `authorization_code_with_pkce` grant is used, and then no secret exists to keep. Refused
|
|
85
|
+
* without that grant.
|
|
86
|
+
* @default false (a confidential client)
|
|
87
|
+
*/
|
|
88
|
+
readonly allowPkceWithoutClientSecret?: boolean;
|
|
89
|
+
/**
|
|
90
|
+
* The URL the app's tile in the App Launcher sends users to. Written on create and on any
|
|
91
|
+
* sync; not drift-checked.
|
|
92
|
+
* @default left out of the write
|
|
93
|
+
*/
|
|
94
|
+
readonly appLauncherUrl?: string;
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
export interface SaasOidcApplicationAttributes {
|
|
98
|
+
/** The Access application UUID. */
|
|
99
|
+
readonly applicationId: string;
|
|
100
|
+
/** The application audience tag, the `aud` of the Access JWTs for this app. */
|
|
101
|
+
readonly aud: string;
|
|
102
|
+
/** The `domain` Cloudflare reports for the app (the OIDC issuer without its scheme). */
|
|
103
|
+
readonly domain: string;
|
|
104
|
+
/** The app's name as Cloudflare reports it. */
|
|
105
|
+
readonly name: string;
|
|
106
|
+
/** The account the app lives in. */
|
|
107
|
+
readonly accountId: string;
|
|
108
|
+
/** The declared team domain (or, for state that predates the prop, the host Cloudflare reports). */
|
|
109
|
+
readonly teamDomain: string;
|
|
110
|
+
/** The OIDC client id, for the relying party's configuration. */
|
|
111
|
+
readonly clientId: string;
|
|
112
|
+
/** `https://<teamDomain>/cdn-cgi/access/sso/oidc/<clientId>`. */
|
|
113
|
+
readonly issuer: string;
|
|
114
|
+
/** `<issuer>/authorization`. */
|
|
115
|
+
readonly authorizationEndpoint: string;
|
|
116
|
+
/** `<issuer>/token`. */
|
|
117
|
+
readonly tokenEndpoint: string;
|
|
118
|
+
/** The signing keys, for a verifier that validates ID tokens. */
|
|
119
|
+
readonly jwksEndpoint: string;
|
|
120
|
+
/** `<issuer>/userinfo`. */
|
|
121
|
+
readonly userinfoEndpoint: string;
|
|
122
|
+
/** `<issuer>/.well-known/openid-configuration`. */
|
|
123
|
+
readonly configurationEndpoint: string;
|
|
124
|
+
/** The redirect URIs the live app permits. */
|
|
125
|
+
readonly redirectUris: ReadonlyArray<string>;
|
|
126
|
+
/** The scopes the live app serves. */
|
|
127
|
+
readonly scopes: ReadonlyArray<string>;
|
|
128
|
+
/** The grant types the live app allows. */
|
|
129
|
+
readonly grantTypes: ReadonlyArray<string>;
|
|
130
|
+
/** The live access token lifetime, or `''` when Cloudflare reports none. */
|
|
131
|
+
readonly accessTokenLifetime: string;
|
|
132
|
+
/** The live refresh token lifetime, or `''` when Cloudflare reports none. */
|
|
133
|
+
readonly refreshTokenLifetime: string;
|
|
134
|
+
/** When Cloudflare created the app, if it says. */
|
|
135
|
+
readonly createdAt: string | undefined;
|
|
136
|
+
/** When Cloudflare last updated the app, if it says. */
|
|
137
|
+
readonly updatedAt: string | undefined;
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=saas-oidc-props.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"saas-oidc-props.d.ts","sourceRoot":"","sources":["../../src/cloudflare/saas-oidc-props.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import * as zeroTrust from '@distilled.cloud/cloudflare/zero-trust';
|
|
2
|
+
import * as Effect from 'effect/Effect';
|
|
3
|
+
import { SaasOidcError } from './saas-oidc-error.ts';
|
|
4
|
+
/**
|
|
5
|
+
* A refusal when the account's organization is read and its domain is not the declared one; else
|
|
6
|
+
* `undefined` (it matches, or it could not be read, see above). Hostnames compare case-insensitively.
|
|
7
|
+
*/
|
|
8
|
+
export declare const checkTeamBeforeCreate: (accountId: string, teamDomain: string) => Effect.Effect<SaasOidcError | undefined, import("@distilled.cloud/cloudflare/Errors").CloudflareError | import("@distilled.cloud/cloudflare/Errors").CloudflareHttpError | import("@distilled.cloud/cloudflare/Errors").CloudflareRateLimited | import("@distilled.cloud/caddy").ConfigError | import("effect/http/HttpClientError").HttpClientError | import("@distilled.cloud/cloudflare/Errors").InvalidRoute | import("@distilled.cloud/cloudflare/Credentials").OAuthRefreshError | zeroTrust.OrganizationNotFound | SaasOidcError | import("@distilled.cloud/cloudflare/Errors").UnknownCloudflareError | import("@distilled.cloud/grafana").DefaultErrors, zeroTrust.CloudflareOpContext>;
|
|
9
|
+
//# sourceMappingURL=saas-oidc-team.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"saas-oidc-team.d.ts","sourceRoot":"","sources":["../../src/cloudflare/saas-oidc-team.ts"],"names":[],"mappings":"AA6BA,OAAO,KAAK,SAAS,MAAM,wCAAwC,CAAC;AACpE,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,aAAa,EAAY,MAAM,sBAAsB,CAAC;AAyB/D;;;GAGG;AACH,eAAO,MAAM,qBAAqB,cAAe,MAAM,cAAc,MAAM,qqBASxE,CAAC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The wire shapes of a SaaS OIDC application, and the parse that reads them: pure, no Effect, no
|
|
3
|
+
* request. saas-oidc-api.ts says why the read is raw JSON (the SDK's responses drop `saas_app`).
|
|
4
|
+
*
|
|
5
|
+
* ⛔ `parseApp` COPIES NAMED FIELDS ONLY, and `client_secret` is not among them: an `ObservedApp`
|
|
6
|
+
* has nowhere to hold the client secret, so no code path can persist or log one.
|
|
7
|
+
*/
|
|
8
|
+
/** The OIDC half of a live SaaS app, from the wire JSON. */
|
|
9
|
+
export interface ObservedSaas {
|
|
10
|
+
readonly authType: string | undefined;
|
|
11
|
+
readonly clientId: string | undefined;
|
|
12
|
+
readonly redirectUris: ReadonlyArray<string> | undefined;
|
|
13
|
+
readonly scopes: ReadonlyArray<string> | undefined;
|
|
14
|
+
readonly grantTypes: ReadonlyArray<string> | undefined;
|
|
15
|
+
readonly accessTokenLifetime: string | undefined;
|
|
16
|
+
readonly refreshTokenLifetime: string | undefined;
|
|
17
|
+
readonly allowPkceWithoutClientSecret: boolean | undefined;
|
|
18
|
+
}
|
|
19
|
+
/** A live Access application as this package sees it. ⛔ There is no secret field, on purpose. */
|
|
20
|
+
export interface ObservedApp {
|
|
21
|
+
readonly id: string | undefined;
|
|
22
|
+
readonly aud: string | undefined;
|
|
23
|
+
readonly type: string | undefined;
|
|
24
|
+
readonly name: string | undefined;
|
|
25
|
+
readonly domain: string | undefined;
|
|
26
|
+
readonly createdAt: string | undefined;
|
|
27
|
+
readonly updatedAt: string | undefined;
|
|
28
|
+
readonly policyIds: ReadonlyArray<string>;
|
|
29
|
+
readonly saasApp: ObservedSaas | undefined;
|
|
30
|
+
}
|
|
31
|
+
/** What a create or an update sends. Built by `writeBody` in saas-oidc-form.ts. */
|
|
32
|
+
export interface AppWrite {
|
|
33
|
+
readonly name: string;
|
|
34
|
+
readonly sessionDuration: string;
|
|
35
|
+
readonly allowedIdps: ReadonlyArray<string> | undefined;
|
|
36
|
+
readonly autoRedirectToIdentity: boolean | undefined;
|
|
37
|
+
readonly appLauncherVisible: boolean;
|
|
38
|
+
readonly policies: ReadonlyArray<string>;
|
|
39
|
+
readonly saasApp: {
|
|
40
|
+
readonly authType: 'oidc';
|
|
41
|
+
readonly redirectUris: ReadonlyArray<string>;
|
|
42
|
+
readonly scopes: ReadonlyArray<string>;
|
|
43
|
+
readonly grantTypes: ReadonlyArray<string>;
|
|
44
|
+
readonly accessTokenLifetime: string;
|
|
45
|
+
readonly refreshTokenOptions?: {
|
|
46
|
+
readonly lifetime: string;
|
|
47
|
+
};
|
|
48
|
+
readonly allowPkceWithoutClientSecret: boolean;
|
|
49
|
+
readonly appLauncherUrl: string | undefined;
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
export declare const record: (value: unknown) => Record<string, unknown> | undefined;
|
|
53
|
+
/**
|
|
54
|
+
* Named fields only, from Cloudflare's snake_case JSON. ⛔ `client_secret` is not among them, and
|
|
55
|
+
* `public_key`, `custom_claims` and `hybrid_and_implicit_options` are not used by this resource.
|
|
56
|
+
*/
|
|
57
|
+
export declare const parseApp: (raw: Record<string, unknown>) => ObservedApp;
|
|
58
|
+
//# sourceMappingURL=saas-oidc-wire.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"saas-oidc-wire.d.ts","sourceRoot":"","sources":["../../src/cloudflare/saas-oidc-wire.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,4DAA4D;AAC5D,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,YAAY,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC;IACzD,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC;IACnD,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC;IACvD,QAAQ,CAAC,mBAAmB,EAAE,MAAM,GAAG,SAAS,CAAC;IACjD,QAAQ,CAAC,oBAAoB,EAAE,MAAM,GAAG,SAAS,CAAC;IAClD,QAAQ,CAAC,4BAA4B,EAAE,OAAO,GAAG,SAAS,CAAC;CAC5D;AAED,iGAAiG;AACjG,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC1C,QAAQ,CAAC,OAAO,EAAE,YAAY,GAAG,SAAS,CAAC;CAC5C;AAED,mFAAmF;AACnF,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,WAAW,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC;IACxD,QAAQ,CAAC,sBAAsB,EAAE,OAAO,GAAG,SAAS,CAAC;IACrD,QAAQ,CAAC,kBAAkB,EAAE,OAAO,CAAC;IACrC,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACzC,QAAQ,CAAC,OAAO,EAAE;QAChB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;QAC1B,QAAQ,CAAC,YAAY,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;QAC7C,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;QACvC,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;QAC3C,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;QACrC,QAAQ,CAAC,mBAAmB,CAAC,EAAE;YAAE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;SAAE,CAAC;QAC7D,QAAQ,CAAC,4BAA4B,EAAE,OAAO,CAAC;QAC/C,QAAQ,CAAC,cAAc,EAAE,MAAM,GAAG,SAAS,CAAC;KAC7C,CAAC;CACH;AAOD,eAAO,MAAM,MAAM,UAAW,OAAO,KAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAGnD,CAAC;AAuBhB;;;GAGG;AACH,eAAO,MAAM,QAAQ,QAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAG,WA2BvD,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `HomeFlare.Access.SaasOidcApplication` — a Cloudflare Access SaaS application that makes Access an
|
|
3
|
+
* OIDC identity provider for one relying party (OpenBao's JWT/OIDC auth, Headlamp, a Kubernetes
|
|
4
|
+
* API server). Usage and the secret rules: docs/saas-oidc.md.
|
|
5
|
+
*
|
|
6
|
+
* 🔴 WHY THIS EXISTS ALONGSIDE `Cloudflare.Access.Application`. Alchemy beta.81's Application has
|
|
7
|
+
* no `saas_app` field (its source mentions `saas` only as a type and in two comments), and
|
|
8
|
+
* `@distilled.cloud/cloudflare` rc.13 decodes a saas app's GET and create response WITHOUT it, so
|
|
9
|
+
* the client id cannot be read back through either. See saas-oidc-api.ts.
|
|
10
|
+
*
|
|
11
|
+
* ⛔ THE TYPE ID IS A STATE KEY, AND THIS ONE WAS MOVED, NOT RENAMED. It is the string the
|
|
12
|
+
* homeflare-openbao stack's live `OpenBaoOidcSaas` row was written under. A different string would
|
|
13
|
+
* make the next plan see a new resource and an orphaned one: a second OIDC app, with a new
|
|
14
|
+
* client id and `aud`, and a delete of the live one unless it were retained. `tests` pin it.
|
|
15
|
+
*
|
|
16
|
+
* ★ `retain` BY DEFAULT, like every kit resource whose deletion breaks its consumers: deleting the
|
|
17
|
+
* app deletes the client id every relying party is configured with. The openbao declaration
|
|
18
|
+
* already pipes `RemovalPolicy.retain()`; `delete` stays fully implemented for a declaration
|
|
19
|
+
* that opts in with `.pipe(RemovalPolicy.destroy())`.
|
|
20
|
+
*/
|
|
21
|
+
import { Credentials } from '@distilled.cloud/cloudflare/Credentials';
|
|
22
|
+
import * as Cloudflare from 'alchemy/Cloudflare';
|
|
23
|
+
import * as Provider from 'alchemy/Provider';
|
|
24
|
+
import { Resource, type ResourceClass } from 'alchemy/Resource';
|
|
25
|
+
import * as HttpClient from 'effect/http/HttpClient';
|
|
26
|
+
import type { Providers } from './providers.ts';
|
|
27
|
+
import type { SaasOidcApplicationAttributes, SaasOidcApplicationProps } from './saas-oidc-form.ts';
|
|
28
|
+
export interface SaasOidcApplication extends Resource<'HomeFlare.Access.SaasOidcApplication', SaasOidcApplicationProps, SaasOidcApplicationAttributes, never, Providers> {
|
|
29
|
+
}
|
|
30
|
+
export declare const SaasOidcApplication: ResourceClass<SaasOidcApplication>;
|
|
31
|
+
/**
|
|
32
|
+
* ★ `Provider.effect`, CAPTURING THE THREE SERVICES AT BUILD, as MeshNodeProvider does
|
|
33
|
+
* (mesh-node.ts): correct whether or not the stack also merges `Cloudflare.providers()`.
|
|
34
|
+
*/
|
|
35
|
+
export declare const SaasOidcApplicationProvider: () => import("effect/Layer").Layer<Provider.Provider<SaasOidcApplication>, never, Cloudflare.CloudflareEnvironment | Credentials | HttpClient.HttpClient | import("alchemy").Stack | import("alchemy").Stage>;
|
|
36
|
+
//# sourceMappingURL=saas-oidc.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"saas-oidc.d.ts","sourceRoot":"","sources":["../../src/cloudflare/saas-oidc.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,yCAAyC,CAAC;AACtE,OAAO,KAAK,UAAU,MAAM,oBAAoB,CAAC;AACjD,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGhE,OAAO,KAAK,UAAU,MAAM,wBAAwB,CAAC;AACrD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD,OAAO,KAAK,EAAE,6BAA6B,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAEnG,MAAM,WAAW,mBAAoB,SAAQ,QAAQ,CACnD,sCAAsC,EACtC,wBAAwB,EACxB,6BAA6B,EAC7B,KAAK,EACL,SAAS,CACV;CAAG;AAEJ,eAAO,MAAM,mBAAmB,EAAE,aAAa,CAAC,mBAAmB,CAG/D,CAAC;AAOL;;;GAGG;AACH,eAAO,MAAM,2BAA2B,+MAqDrC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cluster-adapter-errors.d.ts","sourceRoot":"","sources":["../../src/talos/cluster-adapter-errors.ts"],"names":[],"mappings":";;;AAMA,sEAAsE;AACtE,qBAAa,0BAA2B,SAAQ,gCAA+C;IAC7F,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC,CAAC;IACA,IAAa,OAAO,IAAI,MAAM,CAO7B;CACF;;;;AAED,qFAAqF;AACrF,qBAAa,wBAAyB,SAAQ,8BAA6C;IACzF,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC,CAAC;IACA,IAAa,OAAO,IAAI,MAAM,CAK7B;CACF;;;;AAED,8FAA8F;AAC9F,qBAAa,sBAAuB,SAAQ,4BAA2C;IACrF,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC;CACpB,CAAC;IACA,IAAa,OAAO,IAAI,MAAM,CAQ7B;CACF;;;;AAED,+FAA+F;AAC/F,qBAAa,iBAAkB,SAAQ,uBAAsC;IAC3E,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB,CAAC;IACA,IAAa,OAAO,IAAI,MAAM,CAQ7B;CACF;;;;AAED,oGAAoG;AACpG,qBAAa,oBAAqB,SAAQ,0BAAyC;IACjF,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB,CAAC;IACA,IAAa,OAAO,IAAI,MAAM,CAK7B;CACF;;;;AAED,qGAAqG;AACrG,qBAAa,yBAA0B,SAAQ,+BAA8C;IAC3F,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B,CAAC;IACA,IAAa,OAAO,IAAI,MAAM,CAK7B;CACF;;;;AAED,4DAA4D;AAC5D,qBAAa,oBAAqB,SAAQ,0BAAyC;IACjF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB,CAAC;IACA,IAAa,OAAO,IAAI,MAAM,CAK7B;CACF;;;;AAED,8FAA8F;AAC9F,qBAAa,2BAA4B,SAAQ,iCAAgD;IAC/F,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC;CACpB,CAAC;IACA,IAAa,OAAO,IAAI,MAAM,CAO7B;CACF;;;;AAED,4FAA4F;AAC5F,qBAAa,4BAA6B,SAAQ,kCAAiD;IACjG,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB,CAAC;IACA,IAAa,OAAO,IAAI,MAAM,CAO7B;CACF;;;;AAED,qFAAqF;AACrF,qBAAa,8BAA+B,SAAQ,oCAElD;IACA,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B,CAAC;IACA,IAAa,OAAO,IAAI,MAAM,CAK7B;CACF;;;;AAED,mGAAmG;AACnG,qBAAa,2BAA4B,SAAQ,iCAAgD;IAC/F,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B,CAAC;IACA,IAAa,OAAO,IAAI,MAAM,
|
|
1
|
+
{"version":3,"file":"cluster-adapter-errors.d.ts","sourceRoot":"","sources":["../../src/talos/cluster-adapter-errors.ts"],"names":[],"mappings":"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"}
|
|
@@ -33,7 +33,8 @@
|
|
|
33
33
|
* (`TalosClusterMoved`); a move is a NEW identity resource per physical cluster, so the old
|
|
34
34
|
* rows keep their old uid and their cleanup reaches only the old cluster.
|
|
35
35
|
* ⛔ ONE 10 s DEADLINE covers the vault read AND the uid GET (`withConnectDeadline`): a hung `bao`
|
|
36
|
-
*
|
|
36
|
+
* fails with `TalosOpenBaoConnectTimeout` and the `bao` child is killed. The uid GET has its own
|
|
37
|
+
* 5 s deadline inside it, so a silent apiserver fails first with `TalosClusterIdentityTimeout`.
|
|
37
38
|
* ⚠️ The in-flight HTTPS GET is NOT aborted: upstream `readObject` takes no signal
|
|
38
39
|
* (`internal/client.ts:75`), so the socket lives until the OS gives up. Left for the upstream ask.
|
|
39
40
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cluster-adapter.d.ts","sourceRoot":"","sources":["../../src/talos/cluster-adapter.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"cluster-adapter.d.ts","sourceRoot":"","sources":["../../src/talos/cluster-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AACH,OAAO,EAEL,KAAK,qBAAqB,EAC1B,oBAAoB,EACpB,KAAK,gBAAgB,EACtB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,KAAK,KAAK,QAAQ,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,KAAK,KAAK,mBAAmB,MAAM,oCAAoC,CAAC;AAC/E,OAAO,EACL,KAAK,4BAA4B,EACjC,2BAA2B,EAC3B,KAAK,2BAA2B,EAChC,KAAK,8BAA8B,EACnC,KAAK,yBAAyB,EAC9B,wBAAwB,EACxB,oBAAoB,EACpB,KAAK,0BAA0B,EAC/B,sBAAsB,EACtB,0BAA0B,EAE1B,KAAK,oBAAoB,EAC1B,MAAM,6BAA6B,CAAC;AAErC,OAAO,EAEL,KAAK,mBAAmB,EAGzB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,4BAA4B,EAC5B,2BAA2B,EAC3B,2BAA2B,EAC3B,8BAA8B,EAC9B,iBAAiB,EACjB,yBAAyB,EACzB,wBAAwB,EACxB,oBAAoB,EACpB,0BAA0B,EAC1B,sBAAsB,EACtB,0BAA0B,EAC1B,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,KAAK,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAEvF,OAAO,QAAQ,+BAA+B,CAAC;IAC7C,UAAU,YAAY;QACpB;;;WAGG;QACH,eAAe,EAAE;YACf;;;;eAIG;YACH,GAAG,EAAE,MAAM,CAAC;SACb,CAAC;KACH;CACF;AAED;;;;GAIG;AACH,MAAM,MAAM,kBAAkB,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC,CAAC;AAE/E,kGAAkG;AAClG,MAAM,MAAM,sBAAsB,GAAG,UAAU,GAAG;IAChD,QAAQ,CAAC,IAAI,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;QAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;CACzE,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,sBAAsB,QAAS,MAAM,KAAG,sBAGpD,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,mBAAmB,YACrB,kBAAkB,cACf,UAAU,YACb,QAAQ,CAAC,QAAQ,KACzB,MAAM,CAAC,MAAM,CACd,gBAAgB,EACd,oBAAoB,GACpB,0BAA0B,GAC1B,wBAAwB,GACxB,sBAAsB,GACtB,2BAA2B,GAC3B,4BAA4B,GAC5B,8BAA8B,GAC9B,2BAA2B,GAC3B,0BAA0B,GAC1B,oBAAoB,GACpB,oBAAoB,GACpB,yBAAyB,GACzB,KAAK,EACP,mBAAmB,CAAC,mBAAmB,CAyDrC,CAAC;AAEL;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,WACtB,kBAAkB,KACzB,KAAK,CAAC,KAAK,CAAC,qBAAqB,EAAE,KAAK,EAAE,mBAAmB,CAAC,mBAAmB,CAYjF,CAAC"}
|
package/dist/talos/index.js
CHANGED
|
@@ -71,7 +71,7 @@ class TalosClusterIdentityUnreadable extends Data.TaggedError("TalosClusterIdent
|
|
|
71
71
|
|
|
72
72
|
class TalosClusterIdentityTimeout extends Data.TaggedError("TalosClusterIdentityTimeout") {
|
|
73
73
|
get message() {
|
|
74
|
-
return `talos-openbao cluster '${this.cluster}': no answer to the kube-system uid read within ` + `${this.seconds}s. Refused (failed closed) rather than waiting on a silent apiserver
|
|
74
|
+
return `talos-openbao cluster '${this.cluster}': no answer to the kube-system uid read within ` + `${this.seconds}s (the identity read's own deadline, inside the 10 s connect deadline). ` + "Refused (failed closed) rather than waiting on a silent apiserver.";
|
|
75
75
|
}
|
|
76
76
|
}
|
|
77
77
|
|
|
@@ -240,7 +240,7 @@ var resolveBao = () => {
|
|
|
240
240
|
};
|
|
241
241
|
|
|
242
242
|
// src/talos/mint-temp-file.ts
|
|
243
|
-
import { closeSync, openSync, writeFileSync } from "node:fs";
|
|
243
|
+
import { closeSync, openSync, unlinkSync, writeFileSync } from "node:fs";
|
|
244
244
|
import { unlink } from "node:fs/promises";
|
|
245
245
|
import { randomUUID } from "node:crypto";
|
|
246
246
|
import { tmpdir } from "node:os";
|
|
@@ -252,9 +252,16 @@ var mintKvTempFile = (raw, label) => Effect3.gen(function* () {
|
|
|
252
252
|
try: () => {
|
|
253
253
|
const fd = openSync(path, "wx", 384);
|
|
254
254
|
try {
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
255
|
+
try {
|
|
256
|
+
writeFileSync(fd, raw);
|
|
257
|
+
} finally {
|
|
258
|
+
closeSync(fd);
|
|
259
|
+
}
|
|
260
|
+
} catch (cause) {
|
|
261
|
+
try {
|
|
262
|
+
unlinkSync(path);
|
|
263
|
+
} catch {}
|
|
264
|
+
throw cause;
|
|
258
265
|
}
|
|
259
266
|
},
|
|
260
267
|
catch: (cause) => new Error(`writing ${label} temp file: ${String(cause)}`)
|
|
@@ -590,15 +597,19 @@ var capture = (binary, argv) => Effect8.gen(function* () {
|
|
|
590
597
|
stdout: child.stdout.pipe(Stream3.decodeText, Stream3.mkString, Effect8.map((text) => text.trim()))
|
|
591
598
|
}, { concurrency: "unbounded" })), Effect8.scoped);
|
|
592
599
|
});
|
|
600
|
+
var VERSION_PROBE_TIMEOUT = Duration5.seconds(10);
|
|
593
601
|
var reportsPinnedVersion = (stdout) => stdout.split(/[^\w.+-]+/).includes(TALOSCTL_PINNED_VERSION);
|
|
594
|
-
var checkOverrideVersion = (binary, source) => capture(binary, ["version", "--client"]).pipe(Effect8.
|
|
602
|
+
var checkOverrideVersion = (binary, source, timeout = VERSION_PROBE_TIMEOUT) => capture(binary, ["version", "--client"]).pipe(Effect8.timeoutOrElse({
|
|
603
|
+
duration: timeout,
|
|
604
|
+
orElse: () => Effect8.fail(new TalosBinaryRefused("version --client", `${source} did not answer within ${String(Duration5.toSeconds(timeout))}s`, binary))
|
|
605
|
+
}), Effect8.flatMap((out) => out.exitCode === 0 && reportsPinnedVersion(out.stdout) ? Effect8.void : Effect8.fail(new TalosBinaryRefused("version --client", `${source} is not talosctl ${TALOSCTL_PINNED_VERSION} (exit ${String(out.exitCode)})`, binary))));
|
|
595
606
|
var talosctl = (args, options) => Effect8.gen(function* () {
|
|
596
607
|
const requested = talosctlBinary(options.binary);
|
|
597
608
|
const resolved = requested === DEFAULT_TALOSCTL_BINARY ? yield* resolveDefault(requested) : requested;
|
|
598
609
|
const fromOption = options.binary?.trim();
|
|
599
610
|
const source = requested === DEFAULT_TALOSCTL_BINARY ? "talosctl on PATH" : fromOption !== undefined && fromOption !== "" ? "the `binary` option" : TALOSCTL_BINARY_ENV;
|
|
600
611
|
const binary = yield* checkBinaryPath(resolved, source);
|
|
601
|
-
yield* checkOverrideVersion(binary, source);
|
|
612
|
+
yield* checkOverrideVersion(binary, source, options.versionProbeTimeout);
|
|
602
613
|
const argv = [
|
|
603
614
|
...args,
|
|
604
615
|
"--talosconfig",
|
|
@@ -1074,5 +1085,5 @@ export {
|
|
|
1074
1085
|
talosOpenBaoConnection
|
|
1075
1086
|
};
|
|
1076
1087
|
|
|
1077
|
-
//# debugId=
|
|
1088
|
+
//# debugId=E9E48AF60568B1C664756E2164756E21
|
|
1078
1089
|
//# sourceMappingURL=index.js.map
|