@salamandradevs/core 0.1.4 → 0.2.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 +4 -2
- package/dist/index.js +4 -2
- package/dist/keys/config/index.js +3 -0
- package/dist/keys/config/schema.js +51 -0
- package/dist/keys/config/types.js +2 -0
- package/dist/keys/contracts.js +2 -0
- package/dist/keys/factory.js +61 -0
- package/dist/keys/index.js +10 -0
- package/dist/keys/jose/index.js +3 -0
- package/dist/keys/jose/jose-keyfile.js +97 -0
- package/dist/keys/jose/jose-keys-provider.js +256 -0
- package/dist/keys/jose/schema.js +68 -0
- package/dist/keys/jose/types.js +2 -0
- package/dist/keys/jwks/index.js +2 -0
- package/dist/keys/jwks/jwks-verification-key-provider.js +43 -0
- package/dist/keys/openbao/index.js +3 -0
- package/dist/keys/openbao/openbao-keys-provider.js +461 -0
- package/dist/keys/openbao/schema.js +67 -0
- package/dist/keys/openbao/types.js +2 -0
- package/dist/keys/schema.js +65 -0
- package/dist/keys/types.js +2 -0
- package/dist/keys/validation.js +100 -0
- package/dist/runtime/context.js +42 -0
- package/dist/runtime/index.js +2 -0
- package/dist/storage/records-handler.js +2 -2
- package/dist/tokens/access-token-verifier.js +75 -0
- package/dist/tokens/contracts.js +2 -0
- package/dist/tokens/index.js +5 -0
- package/dist/tokens/schema.js +36 -0
- package/dist/tokens/types.js +2 -0
- package/package.json +2 -1
- package/types/index.d.ts +3 -1
- package/types/index.d.ts.map +1 -1
- package/types/keys/config/index.d.ts +3 -0
- package/types/keys/config/index.d.ts.map +1 -0
- package/types/keys/config/schema.d.ts +66 -0
- package/types/keys/config/schema.d.ts.map +1 -0
- package/types/keys/config/types.d.ts +8 -0
- package/types/keys/config/types.d.ts.map +1 -0
- package/types/keys/contracts.d.ts +52 -0
- package/types/keys/contracts.d.ts.map +1 -0
- package/types/keys/factory.d.ts +22 -0
- package/types/keys/factory.d.ts.map +1 -0
- package/types/keys/index.d.ts +10 -0
- package/types/keys/index.d.ts.map +1 -0
- package/types/keys/jose/index.d.ts +3 -0
- package/types/keys/jose/index.d.ts.map +1 -0
- package/types/keys/jose/jose-keyfile.d.ts +35 -0
- package/types/keys/jose/jose-keyfile.d.ts.map +1 -0
- package/types/keys/jose/jose-keys-provider.d.ts +112 -0
- package/types/keys/jose/jose-keys-provider.d.ts.map +1 -0
- package/types/keys/jose/schema.d.ts +91 -0
- package/types/keys/jose/schema.d.ts.map +1 -0
- package/types/keys/jose/types.d.ts +35 -0
- package/types/keys/jose/types.d.ts.map +1 -0
- package/types/keys/jwks/index.d.ts +2 -0
- package/types/keys/jwks/index.d.ts.map +1 -0
- package/types/keys/jwks/jwks-verification-key-provider.d.ts +27 -0
- package/types/keys/jwks/jwks-verification-key-provider.d.ts.map +1 -0
- package/types/keys/openbao/index.d.ts +3 -0
- package/types/keys/openbao/index.d.ts.map +1 -0
- package/types/keys/openbao/openbao-keys-provider.d.ts +175 -0
- package/types/keys/openbao/openbao-keys-provider.d.ts.map +1 -0
- package/types/keys/openbao/schema.d.ts +68 -0
- package/types/keys/openbao/schema.d.ts.map +1 -0
- package/types/keys/openbao/types.d.ts +52 -0
- package/types/keys/openbao/types.d.ts.map +1 -0
- package/types/keys/schema.d.ts +73 -0
- package/types/keys/schema.d.ts.map +1 -0
- package/types/keys/types.d.ts +53 -0
- package/types/keys/types.d.ts.map +1 -0
- package/types/keys/validation.d.ts +19 -0
- package/types/keys/validation.d.ts.map +1 -0
- package/types/runtime/context.d.ts +67 -0
- package/types/runtime/context.d.ts.map +1 -0
- package/types/runtime/index.d.ts +2 -0
- package/types/runtime/index.d.ts.map +1 -0
- package/types/tokens/access-token-verifier.d.ts +36 -0
- package/types/tokens/access-token-verifier.d.ts.map +1 -0
- package/types/tokens/contracts.d.ts +21 -0
- package/types/tokens/contracts.d.ts.map +1 -0
- package/types/tokens/index.d.ts +5 -0
- package/types/tokens/index.d.ts.map +1 -0
- package/types/tokens/schema.d.ts +34 -0
- package/types/tokens/schema.d.ts.map +1 -0
- package/types/tokens/types.d.ts +20 -0
- package/types/tokens/types.d.ts.map +1 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { KeyFilePayload } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Reads and decrypts the encrypted key file, or reports its absence.
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* A decrypt or parse failure is reported, never swallowed: a wrong passphrase must fail
|
|
7
|
+
* loudly rather than be mistaken for an absent file, so a typo cannot discard the keys.
|
|
8
|
+
* @group Keys
|
|
9
|
+
* @category Key Providers
|
|
10
|
+
* @param filePath - Path to the encrypted key file.
|
|
11
|
+
* @param secret - Passphrase that decrypts the compact JWE.
|
|
12
|
+
* @returns Validated key-file payload, or null when no file exists.
|
|
13
|
+
* @throws {CustomError} KEYS_PROVIDER_ERROR when the file exists but cannot be read,
|
|
14
|
+
* decrypted, or parsed into a valid key-file payload.
|
|
15
|
+
*/
|
|
16
|
+
export declare function readKeyFile(filePath: string, secret: string): Promise<KeyFilePayload | null>;
|
|
17
|
+
/**
|
|
18
|
+
* Encrypts and writes the key file, creating it only when none already exists.
|
|
19
|
+
*
|
|
20
|
+
* @remarks
|
|
21
|
+
* The `wx` flag makes the create exclusive and `0o600` restricts it to the owner, so two
|
|
22
|
+
* processes racing on one host resolve to one winner; the loser sees the file already
|
|
23
|
+
* exists, is told so by the false return, and reads the winner's key instead of minting a
|
|
24
|
+
* second.
|
|
25
|
+
* @group Keys
|
|
26
|
+
* @category Key Providers
|
|
27
|
+
* @param filePath - Path to the encrypted key file.
|
|
28
|
+
* @param secret - Passphrase that encrypts the compact JWE.
|
|
29
|
+
* @param payload - Key-file payload to persist.
|
|
30
|
+
* @returns True when this call created the file, false when one already existed.
|
|
31
|
+
* @throws {CustomError} KEYS_PROVIDER_ERROR when encryption or the write fails for any
|
|
32
|
+
* reason other than the file already existing.
|
|
33
|
+
*/
|
|
34
|
+
export declare function writeKeyFile(filePath: string, secret: string, payload: KeyFilePayload): Promise<boolean>;
|
|
35
|
+
//# sourceMappingURL=jose-keyfile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jose-keyfile.d.ts","sourceRoot":"","sources":["../../../src/keys/jose/jose-keyfile.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AASjD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,WAAW,CAC/B,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAqChC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,YAAY,CAChC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,OAAO,CAAC,CAqBlB"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import type { CryptoKey } from 'jose';
|
|
2
|
+
import type { IKeysProvider } from '../contracts.js';
|
|
3
|
+
import type { PublicJwk, SigningKeyHandle } from '../types.js';
|
|
4
|
+
import type { JoseSigningKeysConfig } from './types.js';
|
|
5
|
+
/**
|
|
6
|
+
* Node.js-native keys provider that keeps its key set in an encrypted local file.
|
|
7
|
+
*
|
|
8
|
+
* @remarks
|
|
9
|
+
* Generates its own ES256 key on first run and keeps the private material in an encrypted
|
|
10
|
+
* file keyed from the environment, then signs and verifies against that one key set. It
|
|
11
|
+
* fits a small deployment: a single host, or replicas sharing one key file, with the file
|
|
12
|
+
* on a persistent volume and the file and `JOSE_KEYFILE_PASSPHRASE` backed up separately.
|
|
13
|
+
* Compared with {@link OpenBaoKeysProvider}, it accepts that the private key lives in
|
|
14
|
+
* process memory, that replacing the key file reissues every credential it signed, and that
|
|
15
|
+
* no policy layer limits key use; OpenBao is the choice when those costs are not
|
|
16
|
+
* acceptable. It serves one active key and never rotates.
|
|
17
|
+
* @group Keys
|
|
18
|
+
* @category Key Providers
|
|
19
|
+
*/
|
|
20
|
+
export declare class JoseKeysProvider implements IKeysProvider {
|
|
21
|
+
private readonly config;
|
|
22
|
+
private readonly algorithm;
|
|
23
|
+
/** Built once in initialize(); no rotation means no refresh machinery. */
|
|
24
|
+
private snapshot;
|
|
25
|
+
/**
|
|
26
|
+
* @param config - Validated Jose provider configuration.
|
|
27
|
+
* @param algorithm - JOSE algorithm enforced for the generated key.
|
|
28
|
+
*/
|
|
29
|
+
constructor(config: JoseSigningKeysConfig, algorithm: 'ES256');
|
|
30
|
+
/**
|
|
31
|
+
* Loads the encrypted key file and publishes the first snapshot, generating a key on
|
|
32
|
+
* first run when the file is absent.
|
|
33
|
+
*
|
|
34
|
+
* @remarks
|
|
35
|
+
* Hard reset: delete the key file and restart. An absent file re-enters the
|
|
36
|
+
* generate-on-empty path and mints a fresh key, so there is no separate reset operation.
|
|
37
|
+
* The file is read once here, so deleting it while the process runs takes effect only on
|
|
38
|
+
* the next initialize(); the running provider keeps serving the key already in memory.
|
|
39
|
+
* This is a hard reset, not a rotation: the previous kid leaves the published key set at
|
|
40
|
+
* once and every credential it signed stops verifying. A decrypt failure fails loudly and
|
|
41
|
+
* is never treated as an empty file, so a wrong passphrase cannot discard the keys.
|
|
42
|
+
* @group Keys
|
|
43
|
+
* @category Key Providers
|
|
44
|
+
* @returns Completed provider initialization.
|
|
45
|
+
* @throws {CustomError} ENV_VAR_ERROR when the passphrase env variable is unset or blank.
|
|
46
|
+
* @throws {CustomError} KEYS_PROVIDER_ERROR when the file cannot be decrypted or violates
|
|
47
|
+
* a signing-key invariant.
|
|
48
|
+
*/
|
|
49
|
+
initialize(): Promise<void>;
|
|
50
|
+
/**
|
|
51
|
+
* Returns a signer bound to the active key.
|
|
52
|
+
*
|
|
53
|
+
* @group Keys
|
|
54
|
+
* @category Key Providers
|
|
55
|
+
* @returns Provider-neutral signing capability.
|
|
56
|
+
* @throws {CustomError} KEYS_PROVIDER_ERROR when initialize() has not completed.
|
|
57
|
+
*/
|
|
58
|
+
getCurrentSigner(): Promise<SigningKeyHandle>;
|
|
59
|
+
/**
|
|
60
|
+
* Resolves one eligible public key by exact key identifier.
|
|
61
|
+
*
|
|
62
|
+
* @group Keys
|
|
63
|
+
* @category Key Providers
|
|
64
|
+
* @param kid - Key identifier carried with the signature.
|
|
65
|
+
* @returns Public verification key, or null for an unknown key.
|
|
66
|
+
* @throws {CustomError} KEYS_PROVIDER_ERROR when initialize() has not completed.
|
|
67
|
+
*/
|
|
68
|
+
getPublicKey(kid: string): Promise<CryptoKey | null>;
|
|
69
|
+
/**
|
|
70
|
+
* Lists the public keys eligible for JWKS publication.
|
|
71
|
+
*
|
|
72
|
+
* @group Keys
|
|
73
|
+
* @category Key Providers
|
|
74
|
+
* @returns Retained public JSON Web Keys.
|
|
75
|
+
* @throws {CustomError} KEYS_PROVIDER_ERROR when initialize() has not completed.
|
|
76
|
+
*/
|
|
77
|
+
listPublicKeys(): Promise<readonly PublicJwk[]>;
|
|
78
|
+
/**
|
|
79
|
+
* Generates the first key and writes it, adopting an existing file when a concurrent
|
|
80
|
+
* start won the race.
|
|
81
|
+
*
|
|
82
|
+
* @param secret - Passphrase that encrypts the key file.
|
|
83
|
+
* @returns The persisted key-file payload.
|
|
84
|
+
* @throws {CustomError} KEYS_PROVIDER_ERROR when the file cannot be written or re-read.
|
|
85
|
+
*/
|
|
86
|
+
private createKeyFile;
|
|
87
|
+
/**
|
|
88
|
+
* Generates one active ES256 key and the key-file payload that persists it.
|
|
89
|
+
*
|
|
90
|
+
* @returns Key-file payload with a single active key and its private material.
|
|
91
|
+
* @throws {CustomError} KEYS_PROVIDER_ERROR when the generated key is missing JWK
|
|
92
|
+
* coordinates.
|
|
93
|
+
*/
|
|
94
|
+
private generatePayload;
|
|
95
|
+
/**
|
|
96
|
+
* Validates the payload and publishes the in-process snapshot.
|
|
97
|
+
*
|
|
98
|
+
* @param payload - Key-file payload to project.
|
|
99
|
+
* @returns Completed snapshot publication.
|
|
100
|
+
* @throws {CustomError} KEYS_PROVIDER_ERROR when the state is invalid or a JWK cannot be
|
|
101
|
+
* imported as an asymmetric key.
|
|
102
|
+
*/
|
|
103
|
+
private publishSnapshot;
|
|
104
|
+
/**
|
|
105
|
+
* Returns the snapshot published by initialize().
|
|
106
|
+
*
|
|
107
|
+
* @returns The in-process projection of the signing-key state.
|
|
108
|
+
* @throws {CustomError} KEYS_PROVIDER_ERROR when initialize() has not completed.
|
|
109
|
+
*/
|
|
110
|
+
private currentSnapshot;
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=jose-keys-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jose-keys-provider.d.ts","sourceRoot":"","sources":["../../../src/keys/jose/jose-keys-provider.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAO,MAAM,MAAM,CAAC;AAK3C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE/D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAIxD;;;;;;;;;;;;;;GAcG;AACH,qBAAa,gBAAiB,YAAW,aAAa;IASlD,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAT5B,0EAA0E;IAC1E,OAAO,CAAC,QAAQ,CAAmC;IAEnD;;;OAGG;gBAEgB,MAAM,EAAE,qBAAqB,EAC7B,SAAS,EAAE,OAAO;IAGrC;;;;;;;;;;;;;;;;;;OAkBG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAcjC;;;;;;;OAOG;IACH,gBAAgB,IAAI,OAAO,CAAC,gBAAgB,CAAC;IAsB7C;;;;;;;;OAQG;IACH,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAIpD;;;;;;;OAOG;IACH,cAAc,IAAI,OAAO,CAAC,SAAS,SAAS,EAAE,CAAC;IAI/C;;;;;;;OAOG;YACW,aAAa;IA4B3B;;;;;;OAMG;YACW,eAAe;IAuD7B;;;;;;;OAOG;YACW,eAAe;IAsD7B;;;;;OAKG;IACH,OAAO,CAAC,eAAe;CAYxB"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* Jose key-file storage schema.
|
|
4
|
+
*
|
|
5
|
+
* - FilePath: Path to the encrypted key file; must be listed in `.gitignore`.
|
|
6
|
+
* - Passphrase: Encrypted key-file passphrase; a secret, read from `JOSE_KEYFILE_PASSPHRASE`.
|
|
7
|
+
*
|
|
8
|
+
* @remarks
|
|
9
|
+
* `passphrase` is marked `.meta({ env })`, so `loadEnvVariables` resolves it from
|
|
10
|
+
* `JOSE_KEYFILE_PASSPHRASE`; the configuration file holds only a placeholder.
|
|
11
|
+
*/
|
|
12
|
+
export declare const joseStorageConfigSchema: z.ZodObject<{
|
|
13
|
+
filePath: z.ZodString;
|
|
14
|
+
passphrase: z.ZodString;
|
|
15
|
+
}, z.core.$strict>;
|
|
16
|
+
/**
|
|
17
|
+
* Jose provider configuration and local-storage schema.
|
|
18
|
+
*
|
|
19
|
+
* - KeyNamePrefix: Prefix for the generated `kid` and provider key identifier.
|
|
20
|
+
* - Storage: Encrypted key-file location and passphrase source.
|
|
21
|
+
*
|
|
22
|
+
* @remarks
|
|
23
|
+
* Self-contained so the provider directory owns its whole storage story without the factory
|
|
24
|
+
* ever handling a file path or a secret.
|
|
25
|
+
*/
|
|
26
|
+
export declare const joseSigningKeysConfigSchema: z.ZodObject<{
|
|
27
|
+
keyNamePrefix: z.ZodString;
|
|
28
|
+
storage: z.ZodObject<{
|
|
29
|
+
filePath: z.ZodString;
|
|
30
|
+
passphrase: z.ZodString;
|
|
31
|
+
}, z.core.$strict>;
|
|
32
|
+
}, z.core.$strict>;
|
|
33
|
+
/**
|
|
34
|
+
* EC P-256 private JWK persisted in the encrypted key file.
|
|
35
|
+
*
|
|
36
|
+
* - Kty: Key type, always `EC`.
|
|
37
|
+
* - Crv: Curve, always `P-256`.
|
|
38
|
+
* - X: Public x coordinate.
|
|
39
|
+
* - Y: Public y coordinate.
|
|
40
|
+
* - D: Private scalar; the secret half, which is why the file is encrypted at rest.
|
|
41
|
+
*/
|
|
42
|
+
export declare const privateJwkSchema: z.ZodObject<{
|
|
43
|
+
kty: z.ZodLiteral<"EC">;
|
|
44
|
+
crv: z.ZodLiteral<"P-256">;
|
|
45
|
+
x: z.ZodString;
|
|
46
|
+
y: z.ZodString;
|
|
47
|
+
d: z.ZodString;
|
|
48
|
+
}, z.core.$strict>;
|
|
49
|
+
/**
|
|
50
|
+
* Decrypted key-file payload.
|
|
51
|
+
*
|
|
52
|
+
* - State: Signing-key lifecycle document shared with every provider.
|
|
53
|
+
* - PrivateJwks: Private signing material indexed by `kid`.
|
|
54
|
+
*/
|
|
55
|
+
export declare const keyFilePayloadSchema: z.ZodObject<{
|
|
56
|
+
state: z.ZodObject<{
|
|
57
|
+
currentKid: z.ZodNullable<z.ZodString>;
|
|
58
|
+
keys: z.ZodArray<z.ZodObject<{
|
|
59
|
+
kid: z.ZodString;
|
|
60
|
+
providerKeyId: z.ZodString;
|
|
61
|
+
status: z.ZodEnum<{
|
|
62
|
+
pending: "pending";
|
|
63
|
+
active: "active";
|
|
64
|
+
retired: "retired";
|
|
65
|
+
}>;
|
|
66
|
+
publicJwk: z.ZodObject<{
|
|
67
|
+
kty: z.ZodString;
|
|
68
|
+
kid: z.ZodString;
|
|
69
|
+
use: z.ZodOptional<z.ZodString>;
|
|
70
|
+
alg: z.ZodOptional<z.ZodString>;
|
|
71
|
+
crv: z.ZodOptional<z.ZodString>;
|
|
72
|
+
x: z.ZodOptional<z.ZodString>;
|
|
73
|
+
y: z.ZodOptional<z.ZodString>;
|
|
74
|
+
n: z.ZodOptional<z.ZodString>;
|
|
75
|
+
e: z.ZodOptional<z.ZodString>;
|
|
76
|
+
}, z.core.$strict>;
|
|
77
|
+
activateAfter: z.ZodPipe<z.ZodString, z.ZodISODateTime>;
|
|
78
|
+
activatedAt: z.ZodNullable<z.ZodPipe<z.ZodString, z.ZodISODateTime>>;
|
|
79
|
+
retiredAt: z.ZodNullable<z.ZodPipe<z.ZodString, z.ZodISODateTime>>;
|
|
80
|
+
verifyUntil: z.ZodNullable<z.ZodPipe<z.ZodString, z.ZodISODateTime>>;
|
|
81
|
+
}, z.core.$strict>>;
|
|
82
|
+
}, z.core.$strict>;
|
|
83
|
+
privateJwks: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
84
|
+
kty: z.ZodLiteral<"EC">;
|
|
85
|
+
crv: z.ZodLiteral<"P-256">;
|
|
86
|
+
x: z.ZodString;
|
|
87
|
+
y: z.ZodString;
|
|
88
|
+
d: z.ZodString;
|
|
89
|
+
}, z.core.$strict>>;
|
|
90
|
+
}, z.core.$strict>;
|
|
91
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/keys/jose/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB;;;;;;;;;GASG;AACH,eAAO,MAAM,uBAAuB;;;kBAQzB,CAAC;AAEZ;;;;;;;;;GASG;AACH,eAAO,MAAM,2BAA2B;;;;;;kBAK7B,CAAC;AAEZ;;;;;;;;GAQG;AACH,eAAO,MAAM,gBAAgB;;;;;;kBAQlB,CAAC;AAEZ;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAKtB,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { CryptoKey } from 'jose';
|
|
2
|
+
import type { z } from 'zod';
|
|
3
|
+
import type { PublicJwk } from '../types.js';
|
|
4
|
+
import type { SigningKeyState } from '../types.js';
|
|
5
|
+
import type { joseSigningKeysConfigSchema } from './schema.js';
|
|
6
|
+
import type { keyFilePayloadSchema } from './schema.js';
|
|
7
|
+
import type { privateJwkSchema } from './schema.js';
|
|
8
|
+
/** Validated Jose provider configuration and local-storage policy. */
|
|
9
|
+
export type JoseSigningKeysConfig = z.infer<typeof joseSigningKeysConfigSchema>;
|
|
10
|
+
/** Decrypted key-file payload persisted by the Jose provider. */
|
|
11
|
+
export type KeyFilePayload = z.infer<typeof keyFilePayloadSchema>;
|
|
12
|
+
/** EC P-256 private JWK persisted in the encrypted key file. */
|
|
13
|
+
export type PrivateJwk = z.infer<typeof privateJwkSchema>;
|
|
14
|
+
/**
|
|
15
|
+
* In-process projection of the Jose provider's signing-key state.
|
|
16
|
+
*
|
|
17
|
+
* - State: Validated lifecycle document the snapshot was built from.
|
|
18
|
+
* - Keys: Public JWK values eligible for JWKS publication.
|
|
19
|
+
* - ByKid: Imported public verification keys indexed by exact key identifier.
|
|
20
|
+
* - ActiveSigner: Active key identifier and its imported private signing key.
|
|
21
|
+
*
|
|
22
|
+
* @remarks
|
|
23
|
+
* Named to match the OpenBao provider's equivalent projection. Built once in `initialize`
|
|
24
|
+
* and never refreshed, because the Jose provider serves one active key and never rotates.
|
|
25
|
+
*/
|
|
26
|
+
export type SigningKeySnapshot = Readonly<{
|
|
27
|
+
state: SigningKeyState;
|
|
28
|
+
keys: readonly PublicJwk[];
|
|
29
|
+
byKid: ReadonlyMap<string, CryptoKey>;
|
|
30
|
+
activeSigner: Readonly<{
|
|
31
|
+
kid: string;
|
|
32
|
+
privateKey: CryptoKey;
|
|
33
|
+
}>;
|
|
34
|
+
}>;
|
|
35
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/keys/jose/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AACtC,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAE7B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,aAAa,CAAC;AAC/D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEpD,sEAAsE;AACtE,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAEhF,iEAAiE;AACjE,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAElE,gEAAgE;AAChE,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,kBAAkB,GAAG,QAAQ,CAAC;IACxC,KAAK,EAAE,eAAe,CAAC;IACvB,IAAI,EAAE,SAAS,SAAS,EAAE,CAAC;IAC3B,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACtC,YAAY,EAAE,QAAQ,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,SAAS,CAAA;KAAE,CAAC,CAAC;CAChE,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/keys/jwks/index.ts"],"names":[],"mappings":"AAAA,cAAc,qCAAqC,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { CryptoKey } from 'jose';
|
|
2
|
+
import type { IVerificationKeyProvider } from '../contracts.js';
|
|
3
|
+
/**
|
|
4
|
+
* Verification keys read from a remote JWKS, such as auth's published key set.
|
|
5
|
+
*
|
|
6
|
+
* @remarks
|
|
7
|
+
* Delegates fetching and caching to `jose`'s remote key set, which refetches on an unknown
|
|
8
|
+
* `kid` after its cooldown. A `kid` the set does not hold resolves to null; a key set that
|
|
9
|
+
* cannot be fetched or parsed is an infrastructure fault.
|
|
10
|
+
* @group Keys
|
|
11
|
+
* @category Key Providers
|
|
12
|
+
*/
|
|
13
|
+
export declare class JwksVerificationKeyProvider implements IVerificationKeyProvider {
|
|
14
|
+
private readonly jwks;
|
|
15
|
+
/** @param jwksUrl - Absolute URL of the JWKS document. */
|
|
16
|
+
constructor(jwksUrl: string);
|
|
17
|
+
/**
|
|
18
|
+
* Resolves an ES256 public key from the remote key set.
|
|
19
|
+
*
|
|
20
|
+
* @param kid - Key identifier carried with the signature.
|
|
21
|
+
* @returns The public key, or null when the key set has no key with that identifier.
|
|
22
|
+
* @throws {CustomError} EXTERNAL_API_ERROR when the key set cannot be fetched or is
|
|
23
|
+
* invalid.
|
|
24
|
+
*/
|
|
25
|
+
getPublicKey(kid: string): Promise<CryptoKey | null>;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=jwks-verification-key-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jwks-verification-key-provider.d.ts","sourceRoot":"","sources":["../../../src/keys/jwks/jwks-verification-key-provider.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AAEtC,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAC;AAEhE;;;;;;;;;GASG;AACH,qBAAa,2BAA4B,YAAW,wBAAwB;IAC1E,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAwC;IAE7D,0DAA0D;gBAC9C,OAAO,EAAE,MAAM;IAI3B;;;;;;;OAOG;IACG,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;CAe3D"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/keys/openbao/index.ts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAC;AAC3C,cAAc,aAAa,CAAC"}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import type { CryptoKey } from 'jose';
|
|
2
|
+
import type { IKeysProvider } from '../contracts.js';
|
|
3
|
+
import type { PublicJwk, SigningKeyHandle } from '../types.js';
|
|
4
|
+
import type { OpenBaoSigningKeysConfig } from './types.js';
|
|
5
|
+
/**
|
|
6
|
+
* Durable OpenBao-backed keys provider that signs with Transit and verifies locally.
|
|
7
|
+
*
|
|
8
|
+
* @remarks
|
|
9
|
+
* Private signing keys never enter this process. OpenBao holds the private material and
|
|
10
|
+
* performs signatures; the signing keys document records which key is active and which
|
|
11
|
+
* retired keys are still verifiable. An operator owns that document and the signing keys it
|
|
12
|
+
* names.
|
|
13
|
+
*
|
|
14
|
+
* It hands a consumer a signer bound to the active key, resolves a public key by `kid` for
|
|
15
|
+
* verification, and lists the public keys eligible for JWKS publication. Its token needs
|
|
16
|
+
* only `read` on the document path and `update` on the signing path; see
|
|
17
|
+
* `docs/en/howto/openbao/README.md` for how keys are provisioned and rotated.
|
|
18
|
+
*
|
|
19
|
+
* Operationally: every signature costs one OpenBao call, so an unreachable or sealed
|
|
20
|
+
* OpenBao stops all issuance. Verification of already-signed credentials is served from the
|
|
21
|
+
* in-process snapshot with no network call, so they survive an outage that blocks new
|
|
22
|
+
* ones.
|
|
23
|
+
* @group Keys
|
|
24
|
+
* @category Key Providers
|
|
25
|
+
*/
|
|
26
|
+
export declare class OpenBaoKeysProvider implements IKeysProvider {
|
|
27
|
+
private readonly config;
|
|
28
|
+
private readonly algorithm;
|
|
29
|
+
private readonly refreshCooldownSecs;
|
|
30
|
+
/** Last validated signing key state, projected for verification and JWKS reads. */
|
|
31
|
+
private snapshot;
|
|
32
|
+
/** Single-flight wrapper over refreshSnapshot; concurrent callers share one document read. */
|
|
33
|
+
private readonly synchronize;
|
|
34
|
+
/** OpenBao origin read from `BAO_ADDR`. */
|
|
35
|
+
private readonly baseUrl;
|
|
36
|
+
/** Runtime OpenBao token read from `BAO_TOKEN`. */
|
|
37
|
+
private readonly token;
|
|
38
|
+
/**
|
|
39
|
+
* @param config - Validated OpenBao key namespace and request policy configuration.
|
|
40
|
+
* @param algorithm - JOSE algorithm enforced for all signing keys.
|
|
41
|
+
* @param refreshCooldownSecs - Minimum time between two re-reads of the lifecycle
|
|
42
|
+
* document triggered by an unknown `kid`; it bounds how often a verification miss may
|
|
43
|
+
* synchronize the snapshot from OpenBao.
|
|
44
|
+
* @throws {CustomError} ENV_VAR_ERROR when `BAO_ADDR` or `BAO_TOKEN` is missing, blank,
|
|
45
|
+
* or malformed.
|
|
46
|
+
*/
|
|
47
|
+
constructor(config: OpenBaoSigningKeysConfig, algorithm: 'ES256', refreshCooldownSecs: number);
|
|
48
|
+
/**
|
|
49
|
+
* Loads the signing keys document and publishes the first snapshot.
|
|
50
|
+
*
|
|
51
|
+
* @group Keys
|
|
52
|
+
* @category Key Providers
|
|
53
|
+
* @returns Completed provider initialization.
|
|
54
|
+
* @throws {CustomError} KEYS_PROVIDER_ERROR when no signing keys document exists or it
|
|
55
|
+
* violates its invariants.
|
|
56
|
+
* @throws {CustomError} EXTERNAL_API_ERROR when OpenBao is unreachable or answers
|
|
57
|
+
* unusably.
|
|
58
|
+
*/
|
|
59
|
+
initialize(): Promise<void>;
|
|
60
|
+
/**
|
|
61
|
+
* Selects the active key and returns a signer bound to that key.
|
|
62
|
+
*
|
|
63
|
+
* @group Keys
|
|
64
|
+
* @category Key Providers
|
|
65
|
+
* @returns Provider-neutral signing capability.
|
|
66
|
+
* @throws {CustomError} KEYS_PROVIDER_ERROR when durable state has no usable active key.
|
|
67
|
+
*/
|
|
68
|
+
getCurrentSigner(): Promise<SigningKeyHandle>;
|
|
69
|
+
/**
|
|
70
|
+
* Resolves one eligible public key by exact key identifier.
|
|
71
|
+
*
|
|
72
|
+
* @group Keys
|
|
73
|
+
* @category Key Providers
|
|
74
|
+
* @param kid - Key identifier carried with the signature.
|
|
75
|
+
* @returns Public verification key, or null for an unknown or expired key.
|
|
76
|
+
* @throws {CustomError} EXTERNAL_API_ERROR when a synchronize is due but OpenBao prevents
|
|
77
|
+
* it, so an outage is never reported as an unknown key.
|
|
78
|
+
*/
|
|
79
|
+
getPublicKey(kid: string): Promise<CryptoKey | null>;
|
|
80
|
+
/**
|
|
81
|
+
* Synchronizes, then lists the keys currently eligible for JWKS publication.
|
|
82
|
+
*
|
|
83
|
+
* @group Keys
|
|
84
|
+
* @category Key Providers
|
|
85
|
+
* @returns Retained public JSON Web Keys.
|
|
86
|
+
* @throws {CustomError} EXTERNAL_API_ERROR when OpenBao prevents the synchronize, so a
|
|
87
|
+
* stale snapshot is never served as though it had succeeded.
|
|
88
|
+
*/
|
|
89
|
+
listPublicKeys(): Promise<readonly PublicJwk[]>;
|
|
90
|
+
/**
|
|
91
|
+
* Returns the published snapshot, synchronizing once if none has been built yet.
|
|
92
|
+
*
|
|
93
|
+
* @returns The most recently published projection of durable signing key state.
|
|
94
|
+
* @throws {CustomError} KEYS_PROVIDER_ERROR when a synchronize completed without
|
|
95
|
+
* publishing.
|
|
96
|
+
*/
|
|
97
|
+
private currentSnapshot;
|
|
98
|
+
/**
|
|
99
|
+
* Reads the signing keys document and rebuilds the published snapshot; the work each
|
|
100
|
+
* synchronize performs.
|
|
101
|
+
*
|
|
102
|
+
* @returns Completed synchronize with a freshly published snapshot.
|
|
103
|
+
* @throws {CustomError} KEYS_PROVIDER_ERROR when no signing keys document exists.
|
|
104
|
+
*/
|
|
105
|
+
private refreshSnapshot;
|
|
106
|
+
/**
|
|
107
|
+
* Signs one exact JWS signing input with a captured signing key.
|
|
108
|
+
*
|
|
109
|
+
* @param providerKeyId - Signing key name captured when the signer was selected.
|
|
110
|
+
* @param input - Exact JWS signing input bytes to sign.
|
|
111
|
+
* @returns Raw 64-byte ES256 signature.
|
|
112
|
+
* @throws {CustomError} EXTERNAL_API_ERROR when OpenBao signs with an unpublished version
|
|
113
|
+
* or returns a signature of the wrong length.
|
|
114
|
+
*/
|
|
115
|
+
private signWithTransit;
|
|
116
|
+
/**
|
|
117
|
+
* Reads and validates the signing keys document, or reports its absence.
|
|
118
|
+
*
|
|
119
|
+
* @returns Validated state, or null when no document exists.
|
|
120
|
+
* @throws {CustomError} KEYS_PROVIDER_ERROR when the document exists but is not a signing
|
|
121
|
+
* keys document, or violates a signing key invariant.
|
|
122
|
+
*/
|
|
123
|
+
private readSigningKeyState;
|
|
124
|
+
/**
|
|
125
|
+
* Projects validated state into the in-memory snapshot that serves verification and JWKS.
|
|
126
|
+
*
|
|
127
|
+
* @param state - Validated signing key state to project.
|
|
128
|
+
* @returns Completed snapshot publication.
|
|
129
|
+
* @throws {CustomError} KEYS_PROVIDER_ERROR when an entry holds a non-public JWK.
|
|
130
|
+
*/
|
|
131
|
+
private publishSnapshot;
|
|
132
|
+
/**
|
|
133
|
+
* Parses a Transit sign response into the raw ES256 signature bytes.
|
|
134
|
+
*
|
|
135
|
+
* @param marshaledSignature - Raw `signature` string returned by Transit's sign endpoint.
|
|
136
|
+
* @param providerKeyId - Transit key name, named in the error when the version is
|
|
137
|
+
* unexpected.
|
|
138
|
+
* @returns Raw 64-byte ES256 signature.
|
|
139
|
+
* @throws {CustomError} EXTERNAL_API_ERROR when Transit signed with an unpublished key
|
|
140
|
+
* version or returned a signature of the wrong length.
|
|
141
|
+
*/
|
|
142
|
+
private parseTransitSignature;
|
|
143
|
+
/**
|
|
144
|
+
* Performs one OpenBao HTTP call and converts every failure into a classified
|
|
145
|
+
* `CustomError`.
|
|
146
|
+
*
|
|
147
|
+
* @param operation - Short label naming the step, retained in the error cause.
|
|
148
|
+
* @param path - Absolute OpenBao API path, including the `/v1` prefix.
|
|
149
|
+
* @param init - Method and body for the request.
|
|
150
|
+
* @param schema - Optional response schema; the body is validated when one is supplied.
|
|
151
|
+
* @param schema.parse - Validator applied to the parsed response body.
|
|
152
|
+
* @returns The validated response body, or the raw body when no schema is supplied.
|
|
153
|
+
* @throws {CustomError} EXTERNAL_API_ERROR on any transport failure, timeout, or
|
|
154
|
+
* non-success status.
|
|
155
|
+
*/
|
|
156
|
+
private request;
|
|
157
|
+
/**
|
|
158
|
+
* Classifies one non-success OpenBao status into an actionable error.
|
|
159
|
+
*
|
|
160
|
+
* @param operation - Short label naming the step.
|
|
161
|
+
* @param path - Absolute OpenBao API path that failed.
|
|
162
|
+
* @param status - HTTP status OpenBao returned.
|
|
163
|
+
* @param raw - Parsed response body, consulted only for its sanitized error list.
|
|
164
|
+
* @returns The classified error, for the caller to throw.
|
|
165
|
+
*/
|
|
166
|
+
private failure;
|
|
167
|
+
/**
|
|
168
|
+
* Narrows an unknown error to the structured cause this class attaches to its failures.
|
|
169
|
+
*
|
|
170
|
+
* @param error - Error to inspect.
|
|
171
|
+
* @returns The cause when the error came from this provider's transport, else undefined.
|
|
172
|
+
*/
|
|
173
|
+
private failureCause;
|
|
174
|
+
}
|
|
175
|
+
//# sourceMappingURL=openbao-keys-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openbao-keys-provider.d.ts","sourceRoot":"","sources":["../../../src/keys/openbao/openbao-keys-provider.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AAOtC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAK/D,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAO3D;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBAAa,mBAAoB,YAAW,aAAa;IAuBrD,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,mBAAmB;IAxBtC,mFAAmF;IACnF,OAAO,CAAC,QAAQ,CAAmC;IAEnD,8FAA8F;IAC9F,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA8C;IAE1E,2CAA2C;IAC3C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IAEjC,mDAAmD;IACnD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAE/B;;;;;;;;OAQG;gBAEgB,MAAM,EAAE,wBAAwB,EAChC,SAAS,EAAE,OAAO,EAClB,mBAAmB,EAAE,MAAM;IAU9C;;;;;;;;;;OAUG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAOjC;;;;;;;OAOG;IACG,gBAAgB,IAAI,OAAO,CAAC,gBAAgB,CAAC;IA8BnD;;;;;;;;;OASG;IACG,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IA+B1D;;;;;;;;OAQG;IACG,cAAc,IAAI,OAAO,CAAC,SAAS,SAAS,EAAE,CAAC;IAUrD;;;;;;OAMG;YACW,eAAe;IAiB7B;;;;;;OAMG;YACW,eAAe;IAkB7B;;;;;;;;OAQG;YACW,eAAe;IAyB7B;;;;;;OAMG;YACW,mBAAmB;IAsDjC;;;;;;OAMG;YACW,eAAe;IAwC7B;;;;;;;;;OASG;IACH,OAAO,CAAC,qBAAqB;IAqC7B;;;;;;;;;;;;OAYG;YACW,OAAO;IAoDrB;;;;;;;;OAQG;IACH,OAAO,CAAC,OAAO;IAoCf;;;;;OAKG;IACH,OAAO,CAAC,YAAY;CAWrB"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* OpenBao key namespace, request policy, and connection schema.
|
|
4
|
+
*
|
|
5
|
+
* - TransitMount: Transit secrets-engine mount.
|
|
6
|
+
* - KvMount: KV v2 secrets-engine mount.
|
|
7
|
+
* - StatePath: KV path containing lifecycle state.
|
|
8
|
+
* - KeyNamePrefix: Prefix for provider-managed Transit keys.
|
|
9
|
+
* - RequestTimeoutMs: Deadline applied to every OpenBao HTTP request.
|
|
10
|
+
* - RefreshCooldownSecs: Minimum time between two re-reads of the lifecycle document
|
|
11
|
+
* triggered by an unknown `kid`.
|
|
12
|
+
* - BaoAddr: OpenBao origin without embedded credentials; read from `BAO_ADDR`.
|
|
13
|
+
* - BaoToken: Runtime OpenBao token; a secret, read from `BAO_TOKEN`.
|
|
14
|
+
*
|
|
15
|
+
* @remarks
|
|
16
|
+
* `baoAddr` and `baoToken` are marked `.meta({ env })`, so `loadEnvVariables` resolves them
|
|
17
|
+
* from `BAO_ADDR` and `BAO_TOKEN` and hands the values to the provider; the configuration
|
|
18
|
+
* file holds only placeholders, so the token never appears in the config object.
|
|
19
|
+
*/
|
|
20
|
+
export declare const openBaoSigningKeysConfigSchema: z.ZodObject<{
|
|
21
|
+
transitMount: z.ZodString;
|
|
22
|
+
kvMount: z.ZodString;
|
|
23
|
+
statePath: z.ZodString;
|
|
24
|
+
keyNamePrefix: z.ZodString;
|
|
25
|
+
requestTimeoutMs: z.ZodDefault<z.ZodNumber>;
|
|
26
|
+
refreshCooldownSecs: z.ZodNumber;
|
|
27
|
+
baoAddr: z.ZodURL;
|
|
28
|
+
baoToken: z.ZodString;
|
|
29
|
+
}, z.core.$strict>;
|
|
30
|
+
/**
|
|
31
|
+
* KV v2 lifecycle-state read response schema.
|
|
32
|
+
*
|
|
33
|
+
* - Data: KV envelope carrying the stored document and its version metadata.
|
|
34
|
+
*
|
|
35
|
+
* @remarks
|
|
36
|
+
* OpenBao wraps every logical response in an envelope carrying `request_id`, `lease_id`,
|
|
37
|
+
* `lease_duration`, `renewable`, `warnings`, `wrap_info`, `auth` and `mount_type`, and the
|
|
38
|
+
* version metadata adds `created_time`, `custom_metadata`, `deletion_time` and `destroyed`.
|
|
39
|
+
* None of these response schemas may be `strict`, because those unmodelled fields are
|
|
40
|
+
* always present. Verified against OpenBao 2.7.0.
|
|
41
|
+
*/
|
|
42
|
+
export declare const openBaoKvReadResponseSchema: z.ZodObject<{
|
|
43
|
+
data: z.ZodObject<{
|
|
44
|
+
data: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
45
|
+
metadata: z.ZodObject<{
|
|
46
|
+
version: z.ZodNumber;
|
|
47
|
+
}, z.core.$strip>;
|
|
48
|
+
}, z.core.$strip>;
|
|
49
|
+
}, z.core.$strip>;
|
|
50
|
+
/**
|
|
51
|
+
* Transit signing response schema.
|
|
52
|
+
*
|
|
53
|
+
* - Data: JWS-formatted signature returned by Transit.
|
|
54
|
+
*/
|
|
55
|
+
export declare const openBaoTransitSignResponseSchema: z.ZodObject<{
|
|
56
|
+
data: z.ZodObject<{
|
|
57
|
+
signature: z.ZodString;
|
|
58
|
+
}, z.core.$strip>;
|
|
59
|
+
}, z.core.$strip>;
|
|
60
|
+
/**
|
|
61
|
+
* OpenBao error response schema.
|
|
62
|
+
*
|
|
63
|
+
* - Errors: Sanitized error messages returned by OpenBao.
|
|
64
|
+
*/
|
|
65
|
+
export declare const openBaoErrorResponseSchema: z.ZodObject<{
|
|
66
|
+
errors: z.ZodArray<z.ZodString>;
|
|
67
|
+
}, z.core.$strip>;
|
|
68
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/keys/openbao/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,8BAA8B;;;;;;;;;kBAchC,CAAC;AAEZ;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,2BAA2B;;;;;;;iBAKtC,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,gCAAgC;;;;iBAE3C,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,0BAA0B;;iBAA4C,CAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { CryptoKey } from 'jose';
|
|
2
|
+
import type { z } from 'zod';
|
|
3
|
+
import type { PublicJwk } from '../types.js';
|
|
4
|
+
import type { SigningKeyEntry, SigningKeyState } from '../types.js';
|
|
5
|
+
import type { openBaoKvReadResponseSchema } from './schema.js';
|
|
6
|
+
import type { openBaoSigningKeysConfigSchema } from './schema.js';
|
|
7
|
+
import type { openBaoTransitSignResponseSchema } from './schema.js';
|
|
8
|
+
/** OpenBao key namespace, request policy, and connection configuration. */
|
|
9
|
+
export type OpenBaoSigningKeysConfig = z.infer<typeof openBaoSigningKeysConfigSchema>;
|
|
10
|
+
/** KV v2 read response containing the lifecycle state document. */
|
|
11
|
+
export type OpenBaoKvReadResponse = z.infer<typeof openBaoKvReadResponseSchema>;
|
|
12
|
+
/** Transit response containing a JWS-formatted signature. */
|
|
13
|
+
export type OpenBaoTransitSignResponse = z.infer<typeof openBaoTransitSignResponseSchema>;
|
|
14
|
+
/**
|
|
15
|
+
* Structured cause attached to every OpenBao transport failure.
|
|
16
|
+
*
|
|
17
|
+
* - Operation: Short label naming the lifecycle step that failed.
|
|
18
|
+
* - Path: OpenBao API path that was requested.
|
|
19
|
+
* - Status: HTTP status returned, absent when the request never completed.
|
|
20
|
+
*/
|
|
21
|
+
export type OpenBaoFailureCause = Readonly<{
|
|
22
|
+
operation: string;
|
|
23
|
+
path: string;
|
|
24
|
+
status?: number;
|
|
25
|
+
}>;
|
|
26
|
+
/**
|
|
27
|
+
* Imported public key and lifecycle metadata retained in the local snapshot.
|
|
28
|
+
*
|
|
29
|
+
* - Key: Imported public Web Crypto verification key.
|
|
30
|
+
* - Status: Durable lifecycle status.
|
|
31
|
+
* - VerifyUntil: Retirement verification deadline, if applicable.
|
|
32
|
+
*/
|
|
33
|
+
export type CachedKey = Readonly<{
|
|
34
|
+
key: CryptoKey;
|
|
35
|
+
status: SigningKeyEntry['status'];
|
|
36
|
+
verifyUntil: string | null;
|
|
37
|
+
}>;
|
|
38
|
+
/**
|
|
39
|
+
* Atomic in-process projection of the last validated lifecycle state.
|
|
40
|
+
*
|
|
41
|
+
* - LoadedAt: Local timestamp when the snapshot was built.
|
|
42
|
+
* - State: Durable state represented by the snapshot.
|
|
43
|
+
* - Keys: Public JWK values eligible for publication.
|
|
44
|
+
* - ByKid: Imported verification keys indexed by exact key identifier.
|
|
45
|
+
*/
|
|
46
|
+
export type SigningKeySnapshot = Readonly<{
|
|
47
|
+
loadedAt: number;
|
|
48
|
+
state: SigningKeyState;
|
|
49
|
+
keys: readonly PublicJwk[];
|
|
50
|
+
byKid: ReadonlyMap<string, CachedKey>;
|
|
51
|
+
}>;
|
|
52
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/keys/openbao/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AACtC,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAE7B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACpE,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,aAAa,CAAC;AAC/D,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,aAAa,CAAC;AAClE,OAAO,KAAK,EAAE,gCAAgC,EAAE,MAAM,aAAa,CAAC;AAEpE,2EAA2E;AAC3E,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,8BAA8B,CAAC,CAAC;AAEtF,mEAAmE;AACnE,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAEhF,6DAA6D;AAC7D,MAAM,MAAM,0BAA0B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gCAAgC,CAAC,CAAC;AAE1F;;;;;;GAMG;AACH,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC;IACzC,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC,CAAC;AAEH;;;;;;GAMG;AACH,MAAM,MAAM,SAAS,GAAG,QAAQ,CAAC;IAC/B,GAAG,EAAE,SAAS,CAAC;IACf,MAAM,EAAE,eAAe,CAAC,QAAQ,CAAC,CAAC;IAClC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B,CAAC,CAAC;AAEH;;;;;;;GAOG;AACH,MAAM,MAAM,kBAAkB,GAAG,QAAQ,CAAC;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,eAAe,CAAC;IACvB,IAAI,EAAE,SAAS,SAAS,EAAE,CAAC;IAC3B,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;CACvC,CAAC,CAAC"}
|