@clef-sh/broker 0.1.7-beta.45

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,29 @@
1
+ export declare class ConfigError extends Error {
2
+ constructor(message: string);
3
+ }
4
+ /** Resolved broker configuration. */
5
+ export interface BrokerConfig {
6
+ identity: string;
7
+ environment: string;
8
+ kmsProvider: string;
9
+ kmsKeyId: string;
10
+ kmsRegion?: string;
11
+ port: number;
12
+ host: string;
13
+ handlerConfig: Record<string, string>;
14
+ }
15
+ /**
16
+ * Resolve broker configuration from environment variables.
17
+ *
18
+ * Required:
19
+ * CLEF_BROKER_IDENTITY, CLEF_BROKER_ENVIRONMENT,
20
+ * CLEF_BROKER_KMS_PROVIDER, CLEF_BROKER_KMS_KEY_ID
21
+ *
22
+ * Optional:
23
+ * CLEF_BROKER_KMS_REGION, CLEF_BROKER_PORT (default 8080),
24
+ * CLEF_BROKER_HOST (default "0.0.0.0")
25
+ *
26
+ * Handler config: all CLEF_BROKER_HANDLER_* vars are collected with the prefix stripped.
27
+ */
28
+ export declare function resolveConfig(env?: Record<string, string | undefined>): BrokerConfig;
29
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,qBAAa,WAAY,SAAQ,KAAK;gBACxB,OAAO,EAAE,MAAM;CAI5B;AAED,qCAAqC;AACrC,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACvC;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAAC,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAe,GAAG,YAAY,CAqCjG"}
package/dist/config.js ADDED
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ConfigError = void 0;
4
+ exports.resolveConfig = resolveConfig;
5
+ const VALID_KMS_PROVIDERS = ["aws", "gcp", "azure"];
6
+ const HANDLER_PREFIX = "CLEF_BROKER_HANDLER_";
7
+ class ConfigError extends Error {
8
+ constructor(message) {
9
+ super(message);
10
+ this.name = "ConfigError";
11
+ }
12
+ }
13
+ exports.ConfigError = ConfigError;
14
+ /**
15
+ * Resolve broker configuration from environment variables.
16
+ *
17
+ * Required:
18
+ * CLEF_BROKER_IDENTITY, CLEF_BROKER_ENVIRONMENT,
19
+ * CLEF_BROKER_KMS_PROVIDER, CLEF_BROKER_KMS_KEY_ID
20
+ *
21
+ * Optional:
22
+ * CLEF_BROKER_KMS_REGION, CLEF_BROKER_PORT (default 8080),
23
+ * CLEF_BROKER_HOST (default "0.0.0.0")
24
+ *
25
+ * Handler config: all CLEF_BROKER_HANDLER_* vars are collected with the prefix stripped.
26
+ */
27
+ function resolveConfig(env = process.env) {
28
+ const identity = env.CLEF_BROKER_IDENTITY;
29
+ if (!identity)
30
+ throw new ConfigError("CLEF_BROKER_IDENTITY is required.");
31
+ const environment = env.CLEF_BROKER_ENVIRONMENT;
32
+ if (!environment)
33
+ throw new ConfigError("CLEF_BROKER_ENVIRONMENT is required.");
34
+ const kmsProvider = env.CLEF_BROKER_KMS_PROVIDER;
35
+ if (!kmsProvider)
36
+ throw new ConfigError("CLEF_BROKER_KMS_PROVIDER is required.");
37
+ if (!VALID_KMS_PROVIDERS.includes(kmsProvider)) {
38
+ throw new ConfigError(`CLEF_BROKER_KMS_PROVIDER must be one of: ${VALID_KMS_PROVIDERS.join(", ")}. Got: "${kmsProvider}"`);
39
+ }
40
+ const kmsKeyId = env.CLEF_BROKER_KMS_KEY_ID;
41
+ if (!kmsKeyId)
42
+ throw new ConfigError("CLEF_BROKER_KMS_KEY_ID is required.");
43
+ const kmsRegion = env.CLEF_BROKER_KMS_REGION;
44
+ const portStr = env.CLEF_BROKER_PORT ?? "8080";
45
+ const port = parseInt(portStr, 10);
46
+ if (isNaN(port) || port < 1 || port > 65535) {
47
+ throw new ConfigError(`CLEF_BROKER_PORT must be 1-65535. Got: "${portStr}"`);
48
+ }
49
+ const host = env.CLEF_BROKER_HOST ?? "0.0.0.0";
50
+ // Collect handler-specific config from CLEF_BROKER_HANDLER_* env vars
51
+ const handlerConfig = {};
52
+ for (const [key, value] of Object.entries(env)) {
53
+ if (key.startsWith(HANDLER_PREFIX) && value !== undefined) {
54
+ handlerConfig[key.slice(HANDLER_PREFIX.length)] = value;
55
+ }
56
+ }
57
+ return { identity, environment, kmsProvider, kmsKeyId, kmsRegion, port, host, handlerConfig };
58
+ }
59
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;;AAmCA,sCAqCC;AAxED,MAAM,mBAAmB,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;AACpD,MAAM,cAAc,GAAG,sBAAsB,CAAC;AAE9C,MAAa,WAAY,SAAQ,KAAK;IACpC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;IAC5B,CAAC;CACF;AALD,kCAKC;AAcD;;;;;;;;;;;;GAYG;AACH,SAAgB,aAAa,CAAC,MAA0C,OAAO,CAAC,GAAG;IACjF,MAAM,QAAQ,GAAG,GAAG,CAAC,oBAAoB,CAAC;IAC1C,IAAI,CAAC,QAAQ;QAAE,MAAM,IAAI,WAAW,CAAC,mCAAmC,CAAC,CAAC;IAE1E,MAAM,WAAW,GAAG,GAAG,CAAC,uBAAuB,CAAC;IAChD,IAAI,CAAC,WAAW;QAAE,MAAM,IAAI,WAAW,CAAC,sCAAsC,CAAC,CAAC;IAEhF,MAAM,WAAW,GAAG,GAAG,CAAC,wBAAwB,CAAC;IACjD,IAAI,CAAC,WAAW;QAAE,MAAM,IAAI,WAAW,CAAC,uCAAuC,CAAC,CAAC;IACjF,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;QAC/C,MAAM,IAAI,WAAW,CACnB,4CAA4C,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,WAAW,GAAG,CACpG,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,GAAG,CAAC,sBAAsB,CAAC;IAC5C,IAAI,CAAC,QAAQ;QAAE,MAAM,IAAI,WAAW,CAAC,qCAAqC,CAAC,CAAC;IAE5E,MAAM,SAAS,GAAG,GAAG,CAAC,sBAAsB,CAAC;IAE7C,MAAM,OAAO,GAAG,GAAG,CAAC,gBAAgB,IAAI,MAAM,CAAC;IAC/C,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IACnC,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,KAAK,EAAE,CAAC;QAC5C,MAAM,IAAI,WAAW,CAAC,2CAA2C,OAAO,GAAG,CAAC,CAAC;IAC/E,CAAC;IAED,MAAM,IAAI,GAAG,GAAG,CAAC,gBAAgB,IAAI,SAAS,CAAC;IAE/C,sEAAsE;IACtE,MAAM,aAAa,GAA2B,EAAE,CAAC;IACjD,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/C,IAAI,GAAG,CAAC,UAAU,CAAC,cAAc,CAAC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YAC1D,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,GAAG,KAAK,CAAC;QAC1D,CAAC;IACH,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC;AAChG,CAAC"}
@@ -0,0 +1,47 @@
1
+ import type { KmsProvider } from "@clef-sh/runtime";
2
+ /** KMS envelope metadata in the artifact. */
3
+ export interface ArtifactEnvelopeField {
4
+ provider: string;
5
+ keyId: string;
6
+ wrappedKey: string;
7
+ algorithm: string;
8
+ }
9
+ /** JSON envelope produced by the broker. Matches the runtime's expected artifact shape. */
10
+ export interface BrokerArtifact {
11
+ version: 1;
12
+ identity: string;
13
+ environment: string;
14
+ packedAt: string;
15
+ revision: string;
16
+ ciphertextHash: string;
17
+ ciphertext: string;
18
+ keys: string[];
19
+ envelope: ArtifactEnvelopeField;
20
+ expiresAt: string;
21
+ }
22
+ /** Options for packEnvelope(). */
23
+ export interface PackEnvelopeOptions {
24
+ /** Service identity name. */
25
+ identity: string;
26
+ /** Target environment. */
27
+ environment: string;
28
+ /** Generated credentials as key-value pairs. */
29
+ data: Record<string, string>;
30
+ /** TTL in seconds — becomes the expiresAt timestamp. */
31
+ ttl: number;
32
+ /** KMS provider instance (from createKmsProvider()). */
33
+ kmsProvider: KmsProvider;
34
+ /** KMS provider name for the envelope field ("aws", "gcp", "azure"). */
35
+ kmsProviderName: string;
36
+ /** KMS key ID/ARN for wrapping. */
37
+ kmsKeyId: string;
38
+ }
39
+ /**
40
+ * Pack credentials into a Clef artifact envelope with KMS envelope encryption.
41
+ *
42
+ * 1. age-encrypt plaintext with an ephemeral key
43
+ * 2. Wrap the ephemeral private key via KMS
44
+ * 3. Return the complete JSON envelope string
45
+ */
46
+ export declare function packEnvelope(options: PackEnvelopeOptions): Promise<string>;
47
+ //# sourceMappingURL=envelope.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"envelope.d.ts","sourceRoot":"","sources":["../src/envelope.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD,6CAA6C;AAC7C,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,2FAA2F;AAC3F,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,CAAC,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,QAAQ,EAAE,qBAAqB,CAAC;IAChC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,kCAAkC;AAClC,MAAM,WAAW,mBAAmB;IAClC,6BAA6B;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,0BAA0B;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,gDAAgD;IAChD,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,wDAAwD;IACxD,GAAG,EAAE,MAAM,CAAC;IACZ,wDAAwD;IACxD,WAAW,EAAE,WAAW,CAAC;IACzB,wEAAwE;IACxE,eAAe,EAAE,MAAM,CAAC;IACxB,mCAAmC;IACnC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;GAMG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,MAAM,CAAC,CA8ChF"}
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.packEnvelope = packEnvelope;
37
+ const crypto = __importStar(require("crypto"));
38
+ /**
39
+ * Pack credentials into a Clef artifact envelope with KMS envelope encryption.
40
+ *
41
+ * 1. age-encrypt plaintext with an ephemeral key
42
+ * 2. Wrap the ephemeral private key via KMS
43
+ * 3. Return the complete JSON envelope string
44
+ */
45
+ async function packEnvelope(options) {
46
+ const { identity, environment, data, ttl, kmsProvider, kmsProviderName, kmsKeyId } = options;
47
+ const plaintext = JSON.stringify(data);
48
+ // Generate ephemeral age key pair
49
+ const { generateIdentity, identityToRecipient, Encrypter } = await Promise.resolve(`${
50
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- dynamic ESM import of CJS-incompatible package
51
+ "age-encryption"}`).then(s => __importStar(require(s)));
52
+ const ephemeralPrivateKey = (await generateIdentity());
53
+ const ephemeralPublicKey = (await identityToRecipient(ephemeralPrivateKey));
54
+ // age-encrypt plaintext to ephemeral public key
55
+ const e = new Encrypter();
56
+ e.addRecipient(ephemeralPublicKey);
57
+ const encrypted = await e.encrypt(plaintext);
58
+ const ciphertext = Buffer.from(encrypted).toString("base64");
59
+ // Wrap the ephemeral private key with KMS
60
+ const wrapped = await kmsProvider.wrap(kmsKeyId, Buffer.from(ephemeralPrivateKey));
61
+ const revision = `${Date.now()}-${crypto.randomBytes(4).toString("hex")}`;
62
+ const ciphertextHash = crypto.createHash("sha256").update(ciphertext).digest("hex");
63
+ const packedAt = new Date().toISOString();
64
+ const expiresAt = new Date(Date.now() + ttl * 1000).toISOString();
65
+ const artifact = {
66
+ version: 1,
67
+ identity,
68
+ environment,
69
+ packedAt,
70
+ revision,
71
+ ciphertextHash,
72
+ ciphertext,
73
+ keys: Object.keys(data),
74
+ envelope: {
75
+ provider: kmsProviderName,
76
+ keyId: kmsKeyId,
77
+ wrappedKey: wrapped.wrappedKey.toString("base64"),
78
+ algorithm: wrapped.algorithm,
79
+ },
80
+ expiresAt,
81
+ };
82
+ return JSON.stringify(artifact, null, 2);
83
+ }
84
+ //# sourceMappingURL=envelope.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"envelope.js","sourceRoot":"","sources":["../src/envelope.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkDA,oCA8CC;AAhGD,+CAAiC;AA2CjC;;;;;;GAMG;AACI,KAAK,UAAU,YAAY,CAAC,OAA4B;IAC7D,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,IAAI,EAAE,GAAG,EAAE,WAAW,EAAE,eAAe,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;IAE7F,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAEvC,kCAAkC;IAClC,MAAM,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,SAAS,EAAE,GAAG;IAC3D,gHAAgH;IAChH,gBAAuB,uCACxB,CAAC;IACF,MAAM,mBAAmB,GAAG,CAAC,MAAM,gBAAgB,EAAE,CAAW,CAAC;IACjE,MAAM,kBAAkB,GAAG,CAAC,MAAM,mBAAmB,CAAC,mBAAmB,CAAC,CAAW,CAAC;IAEtF,gDAAgD;IAChD,MAAM,CAAC,GAAG,IAAI,SAAS,EAAE,CAAC;IAC1B,CAAC,CAAC,YAAY,CAAC,kBAAkB,CAAC,CAAC;IACnC,MAAM,SAAS,GAAG,MAAM,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAC7C,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,SAAuB,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAE3E,0CAA0C;IAC1C,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC;IAEnF,MAAM,QAAQ,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;IAC1E,MAAM,cAAc,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACpF,MAAM,QAAQ,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC1C,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;IAElE,MAAM,QAAQ,GAAmB;QAC/B,OAAO,EAAE,CAAC;QACV,QAAQ;QACR,WAAW;QACX,QAAQ;QACR,QAAQ;QACR,cAAc;QACd,UAAU;QACV,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;QACvB,QAAQ,EAAE;YACR,QAAQ,EAAE,eAAe;YACzB,KAAK,EAAE,QAAQ;YACf,UAAU,EAAE,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC;YACjD,SAAS,EAAE,OAAO,CAAC,SAAS;SAC7B;QACD,SAAS;KACV,CAAC;IAEF,OAAO,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AAC3C,CAAC"}
@@ -0,0 +1,24 @@
1
+ import { BrokerHandler, BrokerInvoker, HandleOptions } from "./types";
2
+ /**
3
+ * Create a broker invoker with built-in caching, revocation, and shutdown.
4
+ *
5
+ * Returns a `BrokerInvoker` with `invoke()` and `shutdown()` methods.
6
+ * State (cache, KMS provider, revocation tracking) lives in the closure
7
+ * and persists across Lambda warm invocations.
8
+ *
9
+ * ```typescript
10
+ * const broker = createHandler(myBroker);
11
+ *
12
+ * // Lambda
13
+ * export const handler = () => broker.invoke();
14
+ * process.on("SIGTERM", () => broker.shutdown());
15
+ *
16
+ * // Express
17
+ * app.get('/', async (req, res) => {
18
+ * const result = await broker.invoke();
19
+ * res.status(result.statusCode).set(result.headers).send(result.body);
20
+ * });
21
+ * ```
22
+ */
23
+ export declare function createHandler(handler: BrokerHandler, options?: Partial<HandleOptions>): BrokerInvoker;
24
+ //# sourceMappingURL=handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../src/handler.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAkB,aAAa,EAAE,aAAa,EAAS,MAAM,SAAS,CAAC;AAa7F;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,aAAa,EACtB,OAAO,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,GAC/B,aAAa,CAyHf"}
@@ -0,0 +1,137 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createHandler = createHandler;
4
+ const runtime_1 = require("@clef-sh/runtime");
5
+ const envelope_1 = require("./envelope");
6
+ const config_1 = require("./config");
7
+ const noop = () => { };
8
+ /**
9
+ * Create a broker invoker with built-in caching, revocation, and shutdown.
10
+ *
11
+ * Returns a `BrokerInvoker` with `invoke()` and `shutdown()` methods.
12
+ * State (cache, KMS provider, revocation tracking) lives in the closure
13
+ * and persists across Lambda warm invocations.
14
+ *
15
+ * ```typescript
16
+ * const broker = createHandler(myBroker);
17
+ *
18
+ * // Lambda
19
+ * export const handler = () => broker.invoke();
20
+ * process.on("SIGTERM", () => broker.shutdown());
21
+ *
22
+ * // Express
23
+ * app.get('/', async (req, res) => {
24
+ * const result = await broker.invoke();
25
+ * res.status(result.statusCode).set(result.headers).send(result.body);
26
+ * });
27
+ * ```
28
+ */
29
+ function createHandler(handler, options) {
30
+ // Resolve config once at creation time (persists across Lambda warm invocations)
31
+ const envConfig = (0, config_1.resolveConfig)();
32
+ const identity = options?.identity ?? envConfig.identity;
33
+ const environment = options?.environment ?? envConfig.environment;
34
+ const kmsProviderName = options?.kmsProvider ?? envConfig.kmsProvider;
35
+ const kmsKeyId = options?.kmsKeyId ?? envConfig.kmsKeyId;
36
+ const kmsRegion = options?.kmsRegion ?? envConfig.kmsRegion;
37
+ const handlerConfig = options?.config ?? envConfig.handlerConfig;
38
+ const onLog = options?.onLog ?? noop;
39
+ // Create KMS provider once, reuse across invocations
40
+ const kms = (0, runtime_1.createKmsProvider)(kmsProviderName, { region: kmsRegion });
41
+ let cached;
42
+ let inflightPromise;
43
+ let validated = false;
44
+ function isCacheValid() {
45
+ if (!cached)
46
+ return false;
47
+ const elapsed = Date.now() - cached.createdAt;
48
+ return elapsed < cached.ttl * 0.8 * 1000;
49
+ }
50
+ async function revokeIfNeeded() {
51
+ if (handler.revoke && cached?.entityId) {
52
+ try {
53
+ await handler.revoke(cached.entityId, handlerConfig);
54
+ onLog("info", `Revoked credential: ${cached.entityId}`, {
55
+ entityId: cached.entityId,
56
+ });
57
+ }
58
+ catch (err) {
59
+ onLog("warn", `Revoke failed (non-fatal): ${err instanceof Error ? err.message : String(err)}`, {
60
+ entityId: cached.entityId,
61
+ error: err instanceof Error ? err.message : String(err),
62
+ });
63
+ }
64
+ }
65
+ }
66
+ async function generateEnvelope() {
67
+ // Revoke previous credential if handler supports it (Tier 2)
68
+ await revokeIfNeeded();
69
+ const result = await handler.create(handlerConfig);
70
+ const body = await (0, envelope_1.packEnvelope)({
71
+ identity,
72
+ environment,
73
+ data: result.data,
74
+ ttl: result.ttl,
75
+ kmsProvider: kms,
76
+ kmsProviderName,
77
+ kmsKeyId,
78
+ });
79
+ cached = {
80
+ body,
81
+ entityId: result.entityId,
82
+ createdAt: Date.now(),
83
+ ttl: result.ttl,
84
+ };
85
+ return {
86
+ statusCode: 200,
87
+ headers: { "Content-Type": "application/json", "Cache-Control": "no-store" },
88
+ body,
89
+ };
90
+ }
91
+ async function invoke() {
92
+ try {
93
+ // Validate connection on first invocation
94
+ if (!validated && handler.validateConnection) {
95
+ const ok = await handler.validateConnection(handlerConfig);
96
+ if (!ok) {
97
+ throw new Error("Broker handler validateConnection() returned false.");
98
+ }
99
+ validated = true;
100
+ }
101
+ else {
102
+ validated = true;
103
+ }
104
+ // Return cached response if still valid
105
+ if (isCacheValid()) {
106
+ return {
107
+ statusCode: 200,
108
+ headers: { "Content-Type": "application/json", "Cache-Control": "no-store" },
109
+ body: cached.body,
110
+ };
111
+ }
112
+ // Mutex: if a generate is already in flight, wait for it
113
+ if (inflightPromise)
114
+ return await inflightPromise;
115
+ inflightPromise = generateEnvelope().finally(() => {
116
+ inflightPromise = undefined;
117
+ });
118
+ return await inflightPromise;
119
+ }
120
+ catch (err) {
121
+ const message = err instanceof Error ? err.message : String(err);
122
+ onLog("error", `Envelope generation failed: ${message}`, {
123
+ error: message,
124
+ });
125
+ return {
126
+ statusCode: 500,
127
+ headers: { "Content-Type": "application/json" },
128
+ body: JSON.stringify({ error: message }),
129
+ };
130
+ }
131
+ }
132
+ async function shutdown() {
133
+ await revokeIfNeeded();
134
+ }
135
+ return { invoke, shutdown };
136
+ }
137
+ //# sourceMappingURL=handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handler.js","sourceRoot":"","sources":["../src/handler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ export { createHandler } from "./handler";
2
+ export { serve } from "./serve";
3
+ export type { BrokerHandler, BrokerCreateResult, BrokerResponse, BrokerInvoker, LogLevel, LogFn, HandleOptions, ServeOptions, BrokerServerHandle, } from "./types";
4
+ export { resolveConfig, ConfigError } from "./config";
5
+ export type { BrokerConfig } from "./config";
6
+ export { packEnvelope } from "./envelope";
7
+ export type { BrokerArtifact, PackEnvelopeOptions, ArtifactEnvelopeField } from "./envelope";
8
+ export { validateBroker, formatResults } from "./validate";
9
+ export type { CheckResult, ValidationResult } from "./validate";
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,YAAY,EACV,aAAa,EACb,kBAAkB,EAClB,cAAc,EACd,aAAa,EACb,QAAQ,EACR,KAAK,EACL,aAAa,EACb,YAAY,EACZ,kBAAkB,GACnB,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACtD,YAAY,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,YAAY,EAAE,cAAc,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAC7F,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3D,YAAY,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.formatResults = exports.validateBroker = exports.packEnvelope = exports.ConfigError = exports.resolveConfig = exports.serve = exports.createHandler = void 0;
4
+ var handler_1 = require("./handler");
5
+ Object.defineProperty(exports, "createHandler", { enumerable: true, get: function () { return handler_1.createHandler; } });
6
+ var serve_1 = require("./serve");
7
+ Object.defineProperty(exports, "serve", { enumerable: true, get: function () { return serve_1.serve; } });
8
+ var config_1 = require("./config");
9
+ Object.defineProperty(exports, "resolveConfig", { enumerable: true, get: function () { return config_1.resolveConfig; } });
10
+ Object.defineProperty(exports, "ConfigError", { enumerable: true, get: function () { return config_1.ConfigError; } });
11
+ var envelope_1 = require("./envelope");
12
+ Object.defineProperty(exports, "packEnvelope", { enumerable: true, get: function () { return envelope_1.packEnvelope; } });
13
+ var validate_1 = require("./validate");
14
+ Object.defineProperty(exports, "validateBroker", { enumerable: true, get: function () { return validate_1.validateBroker; } });
15
+ Object.defineProperty(exports, "formatResults", { enumerable: true, get: function () { return validate_1.formatResults; } });
16
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,qCAA0C;AAAjC,wGAAA,aAAa,OAAA;AACtB,iCAAgC;AAAvB,8FAAA,KAAK,OAAA;AAYd,mCAAsD;AAA7C,uGAAA,aAAa,OAAA;AAAE,qGAAA,WAAW,OAAA;AAEnC,uCAA0C;AAAjC,wGAAA,YAAY,OAAA;AAErB,uCAA2D;AAAlD,0GAAA,cAAc,OAAA;AAAE,yGAAA,aAAa,OAAA"}
@@ -0,0 +1,10 @@
1
+ import { BrokerHandler, ServeOptions, BrokerServerHandle } from "./types";
2
+ /**
3
+ * Start a broker HTTP server that serves Clef artifact envelopes.
4
+ *
5
+ * This is a convenience wrapper around `createHandler()` for long-running
6
+ * processes (containers, VMs). For serverless (Lambda, Cloud Functions),
7
+ * use `createHandler()` directly.
8
+ */
9
+ export declare function serve(handler: BrokerHandler, options?: Partial<ServeOptions>): Promise<BrokerServerHandle>;
10
+ //# sourceMappingURL=serve.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../src/serve.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAI1E;;;;;;GAMG;AACH,wBAAsB,KAAK,CACzB,OAAO,EAAE,aAAa,EACtB,OAAO,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,GAC9B,OAAO,CAAC,kBAAkB,CAAC,CA4D7B"}
package/dist/serve.js ADDED
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.serve = serve;
37
+ const http = __importStar(require("http"));
38
+ const handler_1 = require("./handler");
39
+ const config_1 = require("./config");
40
+ /**
41
+ * Start a broker HTTP server that serves Clef artifact envelopes.
42
+ *
43
+ * This is a convenience wrapper around `createHandler()` for long-running
44
+ * processes (containers, VMs). For serverless (Lambda, Cloud Functions),
45
+ * use `createHandler()` directly.
46
+ */
47
+ async function serve(handler, options) {
48
+ const envConfig = (0, config_1.resolveConfig)();
49
+ const port = options?.port ?? envConfig.port;
50
+ const host = options?.host ?? envConfig.host;
51
+ const onLog = options?.onLog ?? (() => { });
52
+ const broker = (0, handler_1.createHandler)(handler, options);
53
+ const server = http.createServer(async (req, res) => {
54
+ if (req.method !== "GET") {
55
+ res.writeHead(405, { "Content-Type": "application/json" });
56
+ res.end(JSON.stringify({ error: "Method not allowed" }));
57
+ return;
58
+ }
59
+ if (req.url === "/health") {
60
+ res.writeHead(200, { "Content-Type": "application/json" });
61
+ res.end(JSON.stringify({ status: "ok" }));
62
+ return;
63
+ }
64
+ if (req.url !== "/" && req.url !== "") {
65
+ res.writeHead(404, { "Content-Type": "application/json" });
66
+ res.end(JSON.stringify({ error: "Not found" }));
67
+ return;
68
+ }
69
+ const result = await broker.invoke();
70
+ res.writeHead(result.statusCode, result.headers);
71
+ res.end(result.body);
72
+ });
73
+ return new Promise((resolve, reject) => {
74
+ try {
75
+ server.listen(port, host, () => {
76
+ const addr = server.address();
77
+ const boundPort = typeof addr === "object" && addr ? addr.port : port;
78
+ const url = `http://127.0.0.1:${boundPort}`;
79
+ onLog("info", `Broker serving at ${url}`, { port: boundPort });
80
+ resolve({
81
+ url,
82
+ stop: async () => {
83
+ await broker.shutdown();
84
+ await new Promise((resolveClose, rejectClose) => {
85
+ server.close((err) => (err ? rejectClose(err) : resolveClose()));
86
+ const drainTimer = setTimeout(() => {
87
+ server.closeAllConnections();
88
+ }, 3000);
89
+ drainTimer.unref();
90
+ });
91
+ },
92
+ });
93
+ });
94
+ server.on("error", (err) => reject(err));
95
+ }
96
+ catch (err) {
97
+ reject(err);
98
+ }
99
+ });
100
+ }
101
+ //# sourceMappingURL=serve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serve.js","sourceRoot":"","sources":["../src/serve.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,74 @@
1
+ /** Result of a broker's credential generation. */
2
+ export interface BrokerCreateResult {
3
+ /** Generated credentials as key-value pairs. */
4
+ data: Record<string, string>;
5
+ /** Seconds until these credentials expire. */
6
+ ttl: number;
7
+ /** Identifier for revocation tracking (Tier 2 brokers). */
8
+ entityId?: string;
9
+ }
10
+ /**
11
+ * Handler interface that broker authors implement.
12
+ *
13
+ * Only `create` is required. Tier 1 brokers (self-expiring credentials like
14
+ * STS tokens, RDS IAM tokens, OAuth access tokens) only need `create`.
15
+ * Tier 2 brokers (stateful credentials like SQL database users) also
16
+ * implement `revoke`.
17
+ */
18
+ export interface BrokerHandler {
19
+ /** Generate fresh credentials from the given configuration. */
20
+ create(config: Record<string, string>): Promise<BrokerCreateResult>;
21
+ /** Revoke a previously issued credential (Tier 2). */
22
+ revoke?(entityId: string, config: Record<string, string>): Promise<void>;
23
+ /** Validate that the handler can reach its target system. */
24
+ validateConnection?(config: Record<string, string>): Promise<boolean>;
25
+ }
26
+ /** Log levels for broker operational logging. */
27
+ export type LogLevel = "info" | "warn" | "error";
28
+ /** Structured log callback. */
29
+ export type LogFn = (level: LogLevel, message: string, context?: Record<string, unknown>) => void;
30
+ /** Options for `createHandler()`. */
31
+ export interface HandleOptions {
32
+ /** Service identity name embedded in the artifact envelope. */
33
+ identity: string;
34
+ /** Environment name embedded in the artifact envelope. */
35
+ environment: string;
36
+ /** KMS provider name ("aws", "gcp", or "azure"). */
37
+ kmsProvider: string;
38
+ /** KMS key ID/ARN for wrapping the ephemeral age private key. */
39
+ kmsKeyId: string;
40
+ /** KMS region (AWS only). */
41
+ kmsRegion?: string;
42
+ /** Override handler config. Default: collected from CLEF_BROKER_HANDLER_* env vars. */
43
+ config?: Record<string, string>;
44
+ /** Structured log callback for operational events. */
45
+ onLog?: LogFn;
46
+ }
47
+ /** Response from a broker invocation. Maps directly to Lambda/Cloud Function response format. */
48
+ export interface BrokerResponse {
49
+ statusCode: number;
50
+ headers: Record<string, string>;
51
+ body: string;
52
+ }
53
+ /** Handle returned by `createHandler()`. */
54
+ export interface BrokerInvoker {
55
+ /** Generate or return a cached artifact envelope. */
56
+ invoke(): Promise<BrokerResponse>;
57
+ /** Graceful shutdown: revoke the active credential if applicable. */
58
+ shutdown(): Promise<void>;
59
+ }
60
+ /** Options for the `serve()` HTTP server wrapper. */
61
+ export interface ServeOptions extends HandleOptions {
62
+ /** Port to listen on. Default: 8080. */
63
+ port?: number;
64
+ /** Bind address. Default: "0.0.0.0" (broker serves encrypted envelopes, not plaintext). */
65
+ host?: string;
66
+ }
67
+ /** Handle to a running broker server. */
68
+ export interface BrokerServerHandle {
69
+ /** Base URL of the running server (e.g. "http://127.0.0.1:8080"). */
70
+ url: string;
71
+ /** Graceful shutdown: revokes active credential if applicable, then closes. */
72
+ stop: () => Promise<void>;
73
+ }
74
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,kDAAkD;AAClD,MAAM,WAAW,kBAAkB;IACjC,gDAAgD;IAChD,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,8CAA8C;IAC9C,GAAG,EAAE,MAAM,CAAC;IACZ,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,aAAa;IAC5B,+DAA+D;IAC/D,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACpE,sDAAsD;IACtD,MAAM,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzE,6DAA6D;IAC7D,kBAAkB,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACvE;AAED,iDAAiD;AACjD,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAEjD,+BAA+B;AAC/B,MAAM,MAAM,KAAK,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;AAElG,qCAAqC;AACrC,MAAM,WAAW,aAAa;IAC5B,+DAA+D;IAC/D,QAAQ,EAAE,MAAM,CAAC;IACjB,0DAA0D;IAC1D,WAAW,EAAE,MAAM,CAAC;IACpB,oDAAoD;IACpD,WAAW,EAAE,MAAM,CAAC;IACpB,iEAAiE;IACjE,QAAQ,EAAE,MAAM,CAAC;IACjB,6BAA6B;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uFAAuF;IACvF,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,sDAAsD;IACtD,KAAK,CAAC,EAAE,KAAK,CAAC;CACf;AAED,iGAAiG;AACjG,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,EAAE,MAAM,CAAC;CACd;AAED,4CAA4C;AAC5C,MAAM,WAAW,aAAa;IAC5B,qDAAqD;IACrD,MAAM,IAAI,OAAO,CAAC,cAAc,CAAC,CAAC;IAClC,qEAAqE;IACrE,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AAED,qDAAqD;AACrD,MAAM,WAAW,YAAa,SAAQ,aAAa;IACjD,wCAAwC;IACxC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,2FAA2F;IAC3F,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,yCAAyC;AACzC,MAAM,WAAW,kBAAkB;IACjC,qEAAqE;IACrE,GAAG,EAAE,MAAM,CAAC;IACZ,+EAA+E;IAC/E,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B"}
package/dist/types.js ADDED
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,28 @@
1
+ /** Result of a single validation check. */
2
+ export interface CheckResult {
3
+ name: string;
4
+ passed: boolean;
5
+ message: string;
6
+ }
7
+ /** Result of validating a broker directory. */
8
+ export interface ValidationResult {
9
+ passed: boolean;
10
+ checks: CheckResult[];
11
+ }
12
+ /**
13
+ * Validate a broker directory for registry contribution.
14
+ *
15
+ * Checks:
16
+ * 1. broker.yaml exists and is valid YAML
17
+ * 2. All required manifest fields are present and valid
18
+ * 3. handler.ts (or handler.js) exists
19
+ * 4. README.md exists with required sections
20
+ * 5. Inputs array structure is valid
21
+ * 6. Name matches directory name (if inferrable)
22
+ */
23
+ export declare function validateBroker(brokerDir: string): ValidationResult;
24
+ /**
25
+ * Format validation results for terminal output.
26
+ */
27
+ export declare function formatResults(result: ValidationResult): string;
28
+ //# sourceMappingURL=validate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"AAIA,2CAA2C;AAC3C,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,+CAA+C;AAC/C,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,WAAW,EAAE,CAAC;CACvB;AAuBD;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,gBAAgB,CA2JlE;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,CAc9D"}
@@ -0,0 +1,237 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.validateBroker = validateBroker;
37
+ exports.formatResults = formatResults;
38
+ const fs = __importStar(require("fs"));
39
+ const path = __importStar(require("path"));
40
+ const yaml_1 = require("yaml");
41
+ const VALID_PROVIDERS = ["aws", "gcp", "azure", "agnostic"];
42
+ const VALID_TIERS = [1, 2, 3];
43
+ const REQUIRED_MANIFEST_FIELDS = [
44
+ "name",
45
+ "version",
46
+ "description",
47
+ "author",
48
+ "license",
49
+ "provider",
50
+ "tier",
51
+ "inputs",
52
+ ];
53
+ const REQUIRED_README_HEADINGS = [
54
+ "description",
55
+ "prerequisites",
56
+ "configuration",
57
+ "deploy",
58
+ ];
59
+ /**
60
+ * Validate a broker directory for registry contribution.
61
+ *
62
+ * Checks:
63
+ * 1. broker.yaml exists and is valid YAML
64
+ * 2. All required manifest fields are present and valid
65
+ * 3. handler.ts (or handler.js) exists
66
+ * 4. README.md exists with required sections
67
+ * 5. Inputs array structure is valid
68
+ * 6. Name matches directory name (if inferrable)
69
+ */
70
+ function validateBroker(brokerDir) {
71
+ const checks = [];
72
+ function check(name, fn) {
73
+ try {
74
+ const result = fn();
75
+ if (result === true) {
76
+ checks.push({ name, passed: true, message: "OK" });
77
+ }
78
+ else {
79
+ checks.push({ name, passed: false, message: result });
80
+ }
81
+ }
82
+ catch (err) {
83
+ checks.push({
84
+ name,
85
+ passed: false,
86
+ message: err instanceof Error ? err.message : String(err),
87
+ });
88
+ }
89
+ }
90
+ // ── broker.yaml ──────────────────────────────────────────────────────────
91
+ const manifestPath = path.join(brokerDir, "broker.yaml");
92
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- parsed YAML is untyped
93
+ let manifest;
94
+ check("broker.yaml exists", () => {
95
+ if (!fs.existsSync(manifestPath))
96
+ return "broker.yaml not found";
97
+ return true;
98
+ });
99
+ check("broker.yaml is valid YAML", () => {
100
+ const raw = fs.readFileSync(manifestPath, "utf-8");
101
+ manifest = (0, yaml_1.parse)(raw);
102
+ if (!manifest || typeof manifest !== "object")
103
+ return "broker.yaml is empty or not an object";
104
+ return true;
105
+ });
106
+ for (const field of REQUIRED_MANIFEST_FIELDS) {
107
+ check(`manifest.${field} is present`, () => {
108
+ if (!manifest)
109
+ return "broker.yaml could not be parsed";
110
+ if (manifest[field] === undefined || manifest[field] === null) {
111
+ return `Missing required field: ${field}`;
112
+ }
113
+ return true;
114
+ });
115
+ }
116
+ check("manifest.provider is valid", () => {
117
+ if (!manifest)
118
+ return "broker.yaml could not be parsed";
119
+ if (!VALID_PROVIDERS.includes(manifest.provider)) {
120
+ return `provider must be one of: ${VALID_PROVIDERS.join(", ")}. Got: "${manifest.provider}"`;
121
+ }
122
+ return true;
123
+ });
124
+ check("manifest.tier is valid", () => {
125
+ if (!manifest)
126
+ return "broker.yaml could not be parsed";
127
+ if (!VALID_TIERS.includes(Number(manifest.tier))) {
128
+ return `tier must be 1, 2, or 3. Got: ${manifest.tier}`;
129
+ }
130
+ return true;
131
+ });
132
+ check("manifest.version is semver-like", () => {
133
+ if (!manifest)
134
+ return "broker.yaml could not be parsed";
135
+ if (!/^\d+\.\d+\.\d+/.test(String(manifest.version))) {
136
+ return `version should be semver (e.g. "1.0.0"). Got: "${manifest.version}"`;
137
+ }
138
+ return true;
139
+ });
140
+ check("manifest.name is lowercase with hyphens", () => {
141
+ if (!manifest)
142
+ return "broker.yaml could not be parsed";
143
+ if (!/^[a-z][a-z0-9-]*$/.test(String(manifest.name))) {
144
+ return `name must be lowercase with hyphens (e.g. "rds-iam"). Got: "${manifest.name}"`;
145
+ }
146
+ return true;
147
+ });
148
+ check("manifest.inputs is an array", () => {
149
+ if (!manifest)
150
+ return "broker.yaml could not be parsed";
151
+ if (!Array.isArray(manifest.inputs)) {
152
+ return `inputs must be an array. Got: ${typeof manifest.inputs}`;
153
+ }
154
+ return true;
155
+ });
156
+ check("manifest.inputs entries have name and description", () => {
157
+ if (!manifest || !Array.isArray(manifest.inputs))
158
+ return "inputs not available";
159
+ for (let i = 0; i < manifest.inputs.length; i++) {
160
+ const input = manifest.inputs[i];
161
+ if (!input.name)
162
+ return `inputs[${i}] is missing "name"`;
163
+ if (!input.description)
164
+ return `inputs[${i}] is missing "description"`;
165
+ }
166
+ return true;
167
+ });
168
+ // ── handler file ─────────────────────────────────────────────────────────
169
+ check("handler file exists", () => {
170
+ const tsPath = path.join(brokerDir, "handler.ts");
171
+ const jsPath = path.join(brokerDir, "handler.js");
172
+ if (!fs.existsSync(tsPath) && !fs.existsSync(jsPath)) {
173
+ return "handler.ts (or handler.js) not found";
174
+ }
175
+ return true;
176
+ });
177
+ check("handler exports create function", () => {
178
+ const tsPath = path.join(brokerDir, "handler.ts");
179
+ const jsPath = path.join(brokerDir, "handler.js");
180
+ const handlerPath = fs.existsSync(tsPath) ? tsPath : jsPath;
181
+ if (!fs.existsSync(handlerPath))
182
+ return "handler file not found";
183
+ const source = fs.readFileSync(handlerPath, "utf-8");
184
+ // Check for create method/property in export — works for both
185
+ // `export const handler: BrokerHandler = { create: ... }`
186
+ // and `export default { create: ... }`
187
+ // and `export { handler }` with create inside
188
+ if (!source.includes("create")) {
189
+ return 'handler file does not contain "create" — must export a BrokerHandler with a create method';
190
+ }
191
+ return true;
192
+ });
193
+ // ── README.md ────────────────────────────────────────────────────────────
194
+ const readmePath = path.join(brokerDir, "README.md");
195
+ check("README.md exists", () => {
196
+ if (!fs.existsSync(readmePath))
197
+ return "README.md not found";
198
+ return true;
199
+ });
200
+ check("README.md has required sections", () => {
201
+ if (!fs.existsSync(readmePath))
202
+ return "README.md not found";
203
+ const readme = fs.readFileSync(readmePath, "utf-8").toLowerCase();
204
+ const missing = [];
205
+ for (const heading of REQUIRED_README_HEADINGS) {
206
+ // Look for markdown heading containing the keyword
207
+ if (!readme.includes(`# ${heading}`) && !readme.includes(`## ${heading}`)) {
208
+ missing.push(heading);
209
+ }
210
+ }
211
+ if (missing.length > 0) {
212
+ return `README.md is missing required sections: ${missing.join(", ")}`;
213
+ }
214
+ return true;
215
+ });
216
+ return {
217
+ passed: checks.every((c) => c.passed),
218
+ checks,
219
+ };
220
+ }
221
+ /**
222
+ * Format validation results for terminal output.
223
+ */
224
+ function formatResults(result) {
225
+ const lines = [];
226
+ for (const check of result.checks) {
227
+ const icon = check.passed ? "PASS" : "FAIL";
228
+ lines.push(` ${icon} ${check.name}${check.passed ? "" : ` — ${check.message}`}`);
229
+ }
230
+ const total = result.checks.length;
231
+ const passed = result.checks.filter((c) => c.passed).length;
232
+ const failed = total - passed;
233
+ lines.push("");
234
+ lines.push(` ${passed}/${total} checks passed${failed > 0 ? `, ${failed} failed` : ""}`);
235
+ return lines.join("\n");
236
+ }
237
+ //# sourceMappingURL=validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "@clef-sh/broker",
3
+ "version": "0.1.7-beta.45",
4
+ "description": "Runtime harness for Clef dynamic credential brokers",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "https://github.com/clef-sh/clef",
8
+ "directory": "packages/broker"
9
+ },
10
+ "main": "dist/index.js",
11
+ "types": "dist/index.d.ts",
12
+ "files": [
13
+ "dist"
14
+ ],
15
+ "scripts": {
16
+ "build": "tsc",
17
+ "test": "jest",
18
+ "test:coverage": "jest --coverage",
19
+ "test:integration": "jest --config jest.integration.config.js",
20
+ "test:e2e": "npx tsx --test e2e/broker.e2e.test.ts"
21
+ },
22
+ "dependencies": {
23
+ "@clef-sh/runtime": "*",
24
+ "age-encryption": "^0.3.0",
25
+ "yaml": "^2.3.0"
26
+ },
27
+ "optionalDependencies": {
28
+ "@aws-sdk/client-kms": "^3.500.0",
29
+ "@azure/identity": "^4.0.0",
30
+ "@azure/keyvault-keys": "^4.8.0",
31
+ "@google-cloud/kms": "^4.0.0"
32
+ },
33
+ "devDependencies": {
34
+ "@types/jest": "^29.5.0",
35
+ "@types/node": "^20.11.0",
36
+ "jest": "^29.7.0",
37
+ "ts-jest": "^29.1.0",
38
+ "typescript": "^5.4.0"
39
+ },
40
+ "publishConfig": {
41
+ "access": "public",
42
+ "provenance": true
43
+ },
44
+ "license": "MIT"
45
+ }