@dnsid-ai/key-gcp 0.35.0 → 0.36.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 +36 -6
- package/dist/index.cjs +113 -34
- package/dist/index.d.cts +46 -2
- package/dist/index.d.ts +46 -2
- package/dist/index.js +113 -34
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
# @dnsid-ai/key-gcp
|
|
2
2
|
|
|
3
|
-
Optional Node.js Google Cloud KMS provider
|
|
4
|
-
EC_SIGN_ED25519** key
|
|
5
|
-
|
|
3
|
+
Optional Node.js Google Cloud KMS provider that opens existing **software
|
|
4
|
+
EC_SIGN_ED25519** key versions or explicitly creates a pending first version
|
|
5
|
+
through `create()` under an existing compatible CryptoKey. Install this package
|
|
6
|
+
separately from the base SDK; its Google dependency is not required by base SDK
|
|
7
|
+
consumers.
|
|
6
8
|
|
|
7
9
|
```ts
|
|
8
10
|
import { KeyManagementServiceClient } from '@google-cloud/kms';
|
|
@@ -14,13 +16,28 @@ const keyProvider = await GcpCloudKmsKeyProvider.load(new KeyManagementServiceCl
|
|
|
14
16
|
});
|
|
15
17
|
```
|
|
16
18
|
|
|
17
|
-
Use ambient Google credentials with
|
|
19
|
+
Use ambient Google credentials with `cloudkms.cryptoKeyVersions.viewPublicKey`
|
|
20
|
+
and `cloudkms.cryptoKeyVersions.useToSign` permissions. Both initial `create()`
|
|
21
|
+
and rotation through `generateKey()` also require
|
|
22
|
+
`cloudkms.cryptoKeyVersions.create` and `cloudkms.cryptoKeyVersions.get` for
|
|
23
|
+
version creation and readiness metadata reads. Initial `create()` additionally
|
|
24
|
+
requires `cloudkms.cryptoKeys.get` to validate the existing parent. Grant the
|
|
25
|
+
version metadata-read permission before either operation: a readiness read can
|
|
26
|
+
fail after the remote version has already been created.
|
|
18
27
|
The reference must name a numeric immutable version, not a parent or alias. The
|
|
19
28
|
provider exports only the public Ed25519 JWK, with an RFC 7638 thumbprint as `kid`.
|
|
20
29
|
It sends raw data (never a digest) and verifies request/response CRC32C integrity
|
|
21
30
|
and returned version bindings. Google transport and permission errors propagate;
|
|
22
31
|
there is no local signing fallback, key import, or generation during opening.
|
|
23
32
|
|
|
33
|
+
For first-key creation, explicitly call `GcpCloudKmsKeyProvider.create` with an
|
|
34
|
+
existing `ASYMMETRIC_SIGN` CryptoKey parent whose version template is
|
|
35
|
+
`EC_SIGN_ED25519` / `SOFTWARE`; no prior version is required. See the
|
|
36
|
+
[KMS-first setup guide](https://github.com/dnsid-ai/dnsid-ts/blob/main/docs/kms-first-setup.md) for pending-key activation,
|
|
37
|
+
reference handoff, publication boundaries, and failure recovery. Subsequent
|
|
38
|
+
startup must reopen the saved immutable version with `load`, never recreate it;
|
|
39
|
+
normal configuration remains open-only.
|
|
40
|
+
|
|
24
41
|
Configuration selects this optional package with `provider: "google-kms"`, the
|
|
25
42
|
immutable version as `keyRef`, and optional `settings.algorithm: "EdDSA"` (the
|
|
26
43
|
only supported deployment algorithm). SDK composition translates `EdDSA` to the
|
|
@@ -39,7 +56,12 @@ const keySource = {
|
|
|
39
56
|
An explicit `generateKey()` or `generateKey('EdDSA')` creates a pending software
|
|
40
57
|
Ed25519 version under the same CryptoKey. Other requested algorithms are rejected
|
|
41
58
|
before creation. `validateKeyGeneration('EdDSA')` checks algorithm support without
|
|
42
|
-
creating a version.
|
|
59
|
+
creating a version. Like first-key creation, generation waits for the exact created
|
|
60
|
+
version to become enabled, polling pending generation at most 20 times, 250ms apart.
|
|
61
|
+
Transport call deadlines remain caller-owned. Post-create failures retain the known
|
|
62
|
+
version reference and cause; service/integrity failures are not caller-argument
|
|
63
|
+
errors. There is no automatic recreation or deletion on failure.
|
|
64
|
+
Generation does not change deployment configuration or the active signer.
|
|
43
65
|
Pending keys support `jwk` and `signKey`; `activate` drains in-flight signatures
|
|
44
66
|
and blocks new signing while promoting the pending key. `listKeyIds` contains
|
|
45
67
|
only the active ID, or is empty after local supersession. `supersede` and its
|
|
@@ -47,6 +69,14 @@ only the active ID, or is empty after local supersession. `supersede` and its
|
|
|
47
69
|
destroyed. Historical public keys remain available through `jwk`.
|
|
48
70
|
|
|
49
71
|
Lifecycle state is in memory. Applications own durable recovery and publication
|
|
50
|
-
orchestration
|
|
72
|
+
orchestration. For recovery, pass the application's saved immutable A reference
|
|
73
|
+
as `activeKeyVersion` and saved B reference as optional `pendingKeyVersion` to
|
|
74
|
+
`load`. Both versions and public bindings are validated; duplicate versions or
|
|
75
|
+
public-key identities are rejected. B is inserted directly as pending: `jwk` and
|
|
76
|
+
rotation `signKey` are available, while `signingKey`, `sign`, and `listKeyIds`
|
|
77
|
+
continue to select only A. Existing `activate` performs the local transition.
|
|
78
|
+
This input is saved application state, not key discovery or permission to activate;
|
|
79
|
+
managed recovery still validates the saved rotation's exact bindings. Ordinary
|
|
80
|
+
A-only loading is unchanged and does not discover pending state.
|
|
51
81
|
Retained-key configuration loading is rejected. Lifecycle behavior implements
|
|
52
82
|
the provisional shared #56 clarification, not a claim of contract acceptance.
|
package/dist/index.cjs
CHANGED
|
@@ -39,8 +39,10 @@ var GcpCloudKmsKeyProvider = class _GcpCloudKmsKeyProvider {
|
|
|
39
39
|
constructor(client, version, publicKey) {
|
|
40
40
|
this.client = client;
|
|
41
41
|
this.version = version;
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
if (publicKey) {
|
|
43
|
+
this.activeKid = publicKey.kid;
|
|
44
|
+
this.keys.set(publicKey.kid, { version, jwk: publicKey, state: "active" });
|
|
45
|
+
}
|
|
44
46
|
}
|
|
45
47
|
client;
|
|
46
48
|
version;
|
|
@@ -48,10 +50,46 @@ var GcpCloudKmsKeyProvider = class _GcpCloudKmsKeyProvider {
|
|
|
48
50
|
activeKid;
|
|
49
51
|
signing = /* @__PURE__ */ new Set();
|
|
50
52
|
activating = false;
|
|
53
|
+
/**
|
|
54
|
+
* Creates one version under an existing ASYMMETRIC_SIGN CryptoKey with a
|
|
55
|
+
* SOFTWARE EC_SIGN_ED25519 template, without opening any prior version.
|
|
56
|
+
* Returns a locally pending provider and immutable reference; activate(kid)
|
|
57
|
+
* explicitly before initial manager injection. Never provisions the parent,
|
|
58
|
+
* writes files, deletes keys, or closes the caller-owned client.
|
|
59
|
+
* Pending generation polls the same version at most 20 times, 250ms apart.
|
|
60
|
+
* Each transport call uses the caller's client timeout configuration.
|
|
61
|
+
* Failed/indeterminate creation may leave an operator-owned remote version;
|
|
62
|
+
* do not blindly retry. Normal load/configuration remains open-only.
|
|
63
|
+
*/
|
|
64
|
+
static async create(client, config) {
|
|
65
|
+
if (config.algorithm !== "EC_SIGN_ED25519") throw new import_protocol.ArgumentError("Google Cloud KMS algorithm must be EC_SIGN_ED25519");
|
|
66
|
+
if (typeof config.parent !== "string" || !/^projects\/[A-Za-z0-9._:-]+\/locations\/[A-Za-z0-9_-]+\/keyRings\/[A-Za-z0-9_-]+\/cryptoKeys\/[A-Za-z0-9_-]+$/.test(config.parent)) {
|
|
67
|
+
throw new import_protocol.ArgumentError("Google Cloud KMS creation requires a CryptoKey parent");
|
|
68
|
+
}
|
|
69
|
+
if (!client.getCryptoKey || !client.createCryptoKeyVersion) throw new import_protocol.ArgumentError("Google Cloud KMS client does not support initial creation");
|
|
70
|
+
const [raw] = await client.getCryptoKey({ name: config.parent });
|
|
71
|
+
const parent = raw;
|
|
72
|
+
if (parent?.name !== config.parent || parent.purpose !== "ASYMMETRIC_SIGN" && parent.purpose !== 5 || !ed25519Software(parent.versionTemplate)) {
|
|
73
|
+
throw new import_protocol.ArgumentError("Google Cloud KMS requires a compatible signing parent/template");
|
|
74
|
+
}
|
|
75
|
+
const provider = new _GcpCloudKmsKeyProvider(client, config.parent);
|
|
76
|
+
const kid = await provider.generatePendingKey(void 0);
|
|
77
|
+
return { provider, kid, keyRef: provider.keys.get(kid).version };
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Opens the selected active version and, optionally, an application-saved pending
|
|
81
|
+
* version for recovery. Both bindings are validated; the pending key supports
|
|
82
|
+
* JWK lookup and rotation proof signing but is not the active signer or live
|
|
83
|
+
* inventory. No discovery, generation, or activation occurs. Applications own
|
|
84
|
+
* durable references and recovery checks; activate performs the local transition.
|
|
85
|
+
*/
|
|
51
86
|
static async load(client, config) {
|
|
52
87
|
const version = config.activeKeyVersion;
|
|
53
|
-
|
|
54
|
-
|
|
88
|
+
validateVersion(version);
|
|
89
|
+
const pendingVersion = config.pendingKeyVersion;
|
|
90
|
+
if (pendingVersion !== void 0) {
|
|
91
|
+
validateVersion(pendingVersion);
|
|
92
|
+
if (pendingVersion === version) throw new import_protocol.ArgumentError("Google Cloud KMS active and pending versions must differ");
|
|
55
93
|
}
|
|
56
94
|
if (config.algorithm !== "EC_SIGN_ED25519") throw new import_protocol.ArgumentError("Google Cloud KMS algorithm must be EC_SIGN_ED25519");
|
|
57
95
|
if (config.retainedKeyVersions?.length) throw new import_protocol.ArgumentError("Google Cloud KMS retained key loading is not supported");
|
|
@@ -59,26 +97,12 @@ var GcpCloudKmsKeyProvider = class _GcpCloudKmsKeyProvider {
|
|
|
59
97
|
const { KeyManagementServiceClient } = await import("@google-cloud/kms");
|
|
60
98
|
client = new KeyManagementServiceClient();
|
|
61
99
|
}
|
|
62
|
-
const
|
|
63
|
-
const
|
|
64
|
-
if (
|
|
65
|
-
|
|
66
|
-
if (
|
|
67
|
-
|
|
68
|
-
throw new import_protocol.ArgumentError("Google Cloud KMS public PEM checksum mismatch");
|
|
69
|
-
}
|
|
70
|
-
let publicKey;
|
|
71
|
-
try {
|
|
72
|
-
if (!response.pem.startsWith("-----BEGIN PUBLIC KEY-----")) throw new Error();
|
|
73
|
-
const key = (0, import_node_crypto.createPublicKey)({ key: response.pem, format: "pem", type: "spki" });
|
|
74
|
-
if (key.asymmetricKeyType !== "ed25519") throw new Error();
|
|
75
|
-
const exported = key.export({ format: "jwk" });
|
|
76
|
-
publicKey = { kty: "OKP", crv: "Ed25519", x: exported.x, kid: "", alg: "EdDSA", use: "sig" };
|
|
77
|
-
} catch {
|
|
78
|
-
throw new import_protocol.ArgumentError("Google Cloud KMS returned invalid Ed25519 public SPKI");
|
|
79
|
-
}
|
|
80
|
-
publicKey.kid = await (0, import_protocol.jwkThumbprint)(publicKey);
|
|
81
|
-
return new _GcpCloudKmsKeyProvider(client, version, Object.freeze(publicKey));
|
|
100
|
+
const publicKey = await loadPublicKey(client, version);
|
|
101
|
+
const pendingKey = pendingVersion === void 0 ? void 0 : await loadPublicKey(client, pendingVersion);
|
|
102
|
+
if (pendingKey?.kid === publicKey.kid) throw new import_protocol.ArgumentError("Google Cloud KMS pending version has duplicate public key");
|
|
103
|
+
const provider = new _GcpCloudKmsKeyProvider(client, version, publicKey);
|
|
104
|
+
if (pendingKey) provider.keys.set(pendingKey.kid, { version: pendingVersion, jwk: pendingKey, state: "pending" });
|
|
105
|
+
return provider;
|
|
82
106
|
}
|
|
83
107
|
async signingKey() {
|
|
84
108
|
if (!this.activeKid) throw new import_protocol.ArgumentError("Google Cloud KMS has no active key");
|
|
@@ -127,21 +151,46 @@ var GcpCloudKmsKeyProvider = class _GcpCloudKmsKeyProvider {
|
|
|
127
151
|
async validateKeyGeneration(algorithm) {
|
|
128
152
|
if (algorithm !== "EdDSA") throw new import_protocol.ArgumentError(`Google Cloud KMS generation settings do not support ${algorithm}`);
|
|
129
153
|
}
|
|
130
|
-
/**
|
|
154
|
+
/**
|
|
155
|
+
* Explicit operator generation only; defaults to EdDSA and rejects other algorithms before creation.
|
|
156
|
+
* Pending generation polls the exact created version at most 20 times, 250ms apart,
|
|
157
|
+
* using the caller's transport timeouts, just as initial creation does.
|
|
158
|
+
* Returns a locally pending key without changing the active signer. Failures after
|
|
159
|
+
* creation retain the version reference and cause, without retrying or deleting it.
|
|
160
|
+
* Service/integrity failures are not caller-argument errors. Never called by configuration opening.
|
|
161
|
+
*/
|
|
131
162
|
async generateKey(algorithm) {
|
|
163
|
+
return this.generatePendingKey(algorithm);
|
|
164
|
+
}
|
|
165
|
+
async generatePendingKey(algorithm) {
|
|
132
166
|
await this.validateKeyGeneration(algorithm ?? "EdDSA");
|
|
133
167
|
if (!this.client.createCryptoKeyVersion) throw new import_protocol.ArgumentError("Google Cloud KMS client does not support version creation");
|
|
134
|
-
const parent = this.version.slice(0, this.version.lastIndexOf("/cryptoKeyVersions/"));
|
|
168
|
+
const parent = this.version.includes("/cryptoKeyVersions/") ? this.version.slice(0, this.version.lastIndexOf("/cryptoKeyVersions/")) : this.version;
|
|
135
169
|
const [raw] = await this.client.createCryptoKeyVersion({ parent, cryptoKeyVersion: { state: "ENABLED" } });
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
170
|
+
let created = raw;
|
|
171
|
+
const name = created?.name;
|
|
172
|
+
if (typeof name !== "string" || !name.startsWith(parent + "/cryptoKeyVersions/") || !/^[1-9][0-9]*$/.test(name.slice((parent + "/cryptoKeyVersions/").length))) {
|
|
173
|
+
throw new import_protocol.ArgumentError(`Google Cloud KMS created an unexpected key version${typeof name === "string" && name ? `: ${name}` : ""}`);
|
|
174
|
+
}
|
|
175
|
+
try {
|
|
176
|
+
for (let poll = 0; ; poll++) {
|
|
177
|
+
if (created?.name !== name || !ed25519Software(created)) throw new import_protocol.ArgumentError("Google Cloud KMS created an unexpected key version");
|
|
178
|
+
if (created.state === "ENABLED" || created.state === 1) break;
|
|
179
|
+
if (created.state !== "PENDING_GENERATION" && created.state !== 5 || poll >= 20 || !this.client.getCryptoKeyVersion) {
|
|
180
|
+
throw new import_protocol.ArgumentError("Google Cloud KMS version is not ready for signing");
|
|
181
|
+
}
|
|
182
|
+
await new Promise((resolve) => setTimeout(resolve, 250));
|
|
183
|
+
const [metadata] = await this.client.getCryptoKeyVersion({ name });
|
|
184
|
+
created = metadata;
|
|
185
|
+
}
|
|
186
|
+
const pending = await _GcpCloudKmsKeyProvider.load(this.client, { activeKeyVersion: name, algorithm: "EC_SIGN_ED25519" });
|
|
187
|
+
const jwk = await pending.signingKey();
|
|
188
|
+
if (this.keys.has(jwk.kid)) throw new import_protocol.ArgumentError("Google Cloud KMS generated duplicate public key");
|
|
189
|
+
this.keys.set(jwk.kid, { version: name, jwk: Object.freeze(jwk), state: "pending" });
|
|
190
|
+
return jwk.kid;
|
|
191
|
+
} catch (cause) {
|
|
192
|
+
throw new Error(`Google Cloud KMS created version ${name}: ${cause instanceof Error ? cause.message : String(cause)}`, { cause });
|
|
139
193
|
}
|
|
140
|
-
const pending = await _GcpCloudKmsKeyProvider.load(this.client, { activeKeyVersion: created.name, algorithm: "EC_SIGN_ED25519" });
|
|
141
|
-
const jwk = await pending.signingKey();
|
|
142
|
-
if (this.keys.has(jwk.kid)) throw new import_protocol.ArgumentError("Google Cloud KMS generated duplicate public key");
|
|
143
|
-
this.keys.set(jwk.kid, { version: created.name, jwk: Object.freeze(jwk), state: "pending" });
|
|
144
|
-
return jwk.kid;
|
|
145
194
|
}
|
|
146
195
|
async activate(kid) {
|
|
147
196
|
if (this.activating) throw new import_protocol.ArgumentError("Google Cloud KMS activation is already in progress");
|
|
@@ -176,6 +225,33 @@ var GcpCloudKmsKeyProvider = class _GcpCloudKmsKeyProvider {
|
|
|
176
225
|
return this.supersede(kid);
|
|
177
226
|
}
|
|
178
227
|
};
|
|
228
|
+
function validateVersion(version) {
|
|
229
|
+
if (typeof version !== "string" || !/^projects\/[A-Za-z0-9._:-]+\/locations\/[A-Za-z0-9_-]+\/keyRings\/[A-Za-z0-9_-]+\/cryptoKeys\/[A-Za-z0-9_-]+\/cryptoKeyVersions\/[1-9][0-9]*$/.test(version)) {
|
|
230
|
+
throw new import_protocol.ArgumentError("Google Cloud KMS requires an immutable CryptoKeyVersion name");
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
async function loadPublicKey(client, version) {
|
|
234
|
+
const [raw] = await client.getPublicKey({ name: version });
|
|
235
|
+
const response = raw;
|
|
236
|
+
if (response?.name !== version) throw new import_protocol.ArgumentError("Google Cloud KMS public key version mismatch");
|
|
237
|
+
if (response.algorithm !== "EC_SIGN_ED25519" && response.algorithm !== 40) throw new import_protocol.ArgumentError("Google Cloud KMS public key algorithm mismatch");
|
|
238
|
+
if (response.protectionLevel !== "SOFTWARE" && response.protectionLevel !== 1) throw new import_protocol.ArgumentError("Google Cloud KMS public key must use SOFTWARE protection");
|
|
239
|
+
if (typeof response.pem !== "string" || !checksumMatches(Buffer.from(response.pem), response.pemCrc32c)) {
|
|
240
|
+
throw new import_protocol.ArgumentError("Google Cloud KMS public PEM checksum mismatch");
|
|
241
|
+
}
|
|
242
|
+
let publicKey;
|
|
243
|
+
try {
|
|
244
|
+
if (!response.pem.startsWith("-----BEGIN PUBLIC KEY-----")) throw new Error();
|
|
245
|
+
const key = (0, import_node_crypto.createPublicKey)({ key: response.pem, format: "pem", type: "spki" });
|
|
246
|
+
if (key.asymmetricKeyType !== "ed25519") throw new Error();
|
|
247
|
+
const exported = key.export({ format: "jwk" });
|
|
248
|
+
publicKey = { kty: "OKP", crv: "Ed25519", x: exported.x, kid: "", alg: "EdDSA", use: "sig" };
|
|
249
|
+
} catch {
|
|
250
|
+
throw new import_protocol.ArgumentError("Google Cloud KMS returned invalid Ed25519 public SPKI");
|
|
251
|
+
}
|
|
252
|
+
publicKey.kid = await (0, import_protocol.jwkThumbprint)(publicKey);
|
|
253
|
+
return Object.freeze(publicKey);
|
|
254
|
+
}
|
|
179
255
|
function checksumMatches(bytes, checksum) {
|
|
180
256
|
const raw = checksum?.value;
|
|
181
257
|
if (raw === void 0 || raw === null) return false;
|
|
@@ -192,6 +268,9 @@ function crc32c(bytes) {
|
|
|
192
268
|
}
|
|
193
269
|
return (crc ^ 4294967295) >>> 0;
|
|
194
270
|
}
|
|
271
|
+
function ed25519Software(value) {
|
|
272
|
+
return !!value && (value.algorithm === "EC_SIGN_ED25519" || value.algorithm === 40) && (value.protectionLevel === "SOFTWARE" || value.protectionLevel === 1);
|
|
273
|
+
}
|
|
195
274
|
// Annotate the CommonJS export names for ESM import in node:
|
|
196
275
|
0 && (module.exports = {
|
|
197
276
|
GcpCloudKmsKeyProvider
|
package/dist/index.d.cts
CHANGED
|
@@ -3,6 +3,8 @@ import { KeyProvider, DnsIdJWK } from '@dnsid-ai/protocol';
|
|
|
3
3
|
interface GcpCloudKmsConfig {
|
|
4
4
|
/** Fully qualified immutable CryptoKeyVersion resource name. */
|
|
5
5
|
activeKeyVersion: string;
|
|
6
|
+
/** Application-saved immutable pending version; never discovered or activated by load. */
|
|
7
|
+
pendingKeyVersion?: string;
|
|
6
8
|
/** Retained-key loading is not supported by this runtime slice. */
|
|
7
9
|
retainedKeyVersions?: string[];
|
|
8
10
|
/** Must be EC_SIGN_ED25519. */
|
|
@@ -10,6 +12,14 @@ interface GcpCloudKmsConfig {
|
|
|
10
12
|
}
|
|
11
13
|
/** Structural seam implemented by the official KeyManagementServiceClient. */
|
|
12
14
|
interface GcpCloudKmsClient {
|
|
15
|
+
/** Required only for initial creation; reads the existing signing parent/template. */
|
|
16
|
+
getCryptoKey?(request: {
|
|
17
|
+
name: string;
|
|
18
|
+
}): Promise<readonly unknown[]>;
|
|
19
|
+
/** Required when a newly created version is still PENDING_GENERATION. */
|
|
20
|
+
getCryptoKeyVersion?(request: {
|
|
21
|
+
name: string;
|
|
22
|
+
}): Promise<readonly unknown[]>;
|
|
13
23
|
createCryptoKeyVersion?(request: {
|
|
14
24
|
parent: string;
|
|
15
25
|
cryptoKeyVersion: {
|
|
@@ -27,7 +37,7 @@ interface GcpCloudKmsClient {
|
|
|
27
37
|
};
|
|
28
38
|
}): Promise<readonly unknown[]>;
|
|
29
39
|
}
|
|
30
|
-
/** Opens
|
|
40
|
+
/** Opens existing software Ed25519 versions, or explicitly creates pending versions. */
|
|
31
41
|
declare class GcpCloudKmsKeyProvider implements KeyProvider {
|
|
32
42
|
private readonly client;
|
|
33
43
|
private readonly version;
|
|
@@ -36,6 +46,32 @@ declare class GcpCloudKmsKeyProvider implements KeyProvider {
|
|
|
36
46
|
private readonly signing;
|
|
37
47
|
private activating;
|
|
38
48
|
private constructor();
|
|
49
|
+
/**
|
|
50
|
+
* Creates one version under an existing ASYMMETRIC_SIGN CryptoKey with a
|
|
51
|
+
* SOFTWARE EC_SIGN_ED25519 template, without opening any prior version.
|
|
52
|
+
* Returns a locally pending provider and immutable reference; activate(kid)
|
|
53
|
+
* explicitly before initial manager injection. Never provisions the parent,
|
|
54
|
+
* writes files, deletes keys, or closes the caller-owned client.
|
|
55
|
+
* Pending generation polls the same version at most 20 times, 250ms apart.
|
|
56
|
+
* Each transport call uses the caller's client timeout configuration.
|
|
57
|
+
* Failed/indeterminate creation may leave an operator-owned remote version;
|
|
58
|
+
* do not blindly retry. Normal load/configuration remains open-only.
|
|
59
|
+
*/
|
|
60
|
+
static create(client: GcpCloudKmsClient, config: {
|
|
61
|
+
parent: string;
|
|
62
|
+
algorithm: string;
|
|
63
|
+
}): Promise<{
|
|
64
|
+
provider: GcpCloudKmsKeyProvider;
|
|
65
|
+
kid: string;
|
|
66
|
+
keyRef: string;
|
|
67
|
+
}>;
|
|
68
|
+
/**
|
|
69
|
+
* Opens the selected active version and, optionally, an application-saved pending
|
|
70
|
+
* version for recovery. Both bindings are validated; the pending key supports
|
|
71
|
+
* JWK lookup and rotation proof signing but is not the active signer or live
|
|
72
|
+
* inventory. No discovery, generation, or activation occurs. Applications own
|
|
73
|
+
* durable references and recovery checks; activate performs the local transition.
|
|
74
|
+
*/
|
|
39
75
|
static load(client: GcpCloudKmsClient | undefined, config: GcpCloudKmsConfig): Promise<GcpCloudKmsKeyProvider>;
|
|
40
76
|
signingKey(): Promise<DnsIdJWK>;
|
|
41
77
|
jwk(kid: string): Promise<DnsIdJWK>;
|
|
@@ -49,8 +85,16 @@ declare class GcpCloudKmsKeyProvider implements KeyProvider {
|
|
|
49
85
|
signKey(kid: string, payload: Uint8Array): Promise<Uint8Array>;
|
|
50
86
|
private signVersion;
|
|
51
87
|
validateKeyGeneration(algorithm: string): Promise<void>;
|
|
52
|
-
/**
|
|
88
|
+
/**
|
|
89
|
+
* Explicit operator generation only; defaults to EdDSA and rejects other algorithms before creation.
|
|
90
|
+
* Pending generation polls the exact created version at most 20 times, 250ms apart,
|
|
91
|
+
* using the caller's transport timeouts, just as initial creation does.
|
|
92
|
+
* Returns a locally pending key without changing the active signer. Failures after
|
|
93
|
+
* creation retain the version reference and cause, without retrying or deleting it.
|
|
94
|
+
* Service/integrity failures are not caller-argument errors. Never called by configuration opening.
|
|
95
|
+
*/
|
|
53
96
|
generateKey(algorithm?: string): Promise<string>;
|
|
97
|
+
private generatePendingKey;
|
|
54
98
|
activate(kid: string): Promise<void>;
|
|
55
99
|
/**
|
|
56
100
|
* Removes local signing eligibility from an active, pending, or already
|
package/dist/index.d.ts
CHANGED
|
@@ -3,6 +3,8 @@ import { KeyProvider, DnsIdJWK } from '@dnsid-ai/protocol';
|
|
|
3
3
|
interface GcpCloudKmsConfig {
|
|
4
4
|
/** Fully qualified immutable CryptoKeyVersion resource name. */
|
|
5
5
|
activeKeyVersion: string;
|
|
6
|
+
/** Application-saved immutable pending version; never discovered or activated by load. */
|
|
7
|
+
pendingKeyVersion?: string;
|
|
6
8
|
/** Retained-key loading is not supported by this runtime slice. */
|
|
7
9
|
retainedKeyVersions?: string[];
|
|
8
10
|
/** Must be EC_SIGN_ED25519. */
|
|
@@ -10,6 +12,14 @@ interface GcpCloudKmsConfig {
|
|
|
10
12
|
}
|
|
11
13
|
/** Structural seam implemented by the official KeyManagementServiceClient. */
|
|
12
14
|
interface GcpCloudKmsClient {
|
|
15
|
+
/** Required only for initial creation; reads the existing signing parent/template. */
|
|
16
|
+
getCryptoKey?(request: {
|
|
17
|
+
name: string;
|
|
18
|
+
}): Promise<readonly unknown[]>;
|
|
19
|
+
/** Required when a newly created version is still PENDING_GENERATION. */
|
|
20
|
+
getCryptoKeyVersion?(request: {
|
|
21
|
+
name: string;
|
|
22
|
+
}): Promise<readonly unknown[]>;
|
|
13
23
|
createCryptoKeyVersion?(request: {
|
|
14
24
|
parent: string;
|
|
15
25
|
cryptoKeyVersion: {
|
|
@@ -27,7 +37,7 @@ interface GcpCloudKmsClient {
|
|
|
27
37
|
};
|
|
28
38
|
}): Promise<readonly unknown[]>;
|
|
29
39
|
}
|
|
30
|
-
/** Opens
|
|
40
|
+
/** Opens existing software Ed25519 versions, or explicitly creates pending versions. */
|
|
31
41
|
declare class GcpCloudKmsKeyProvider implements KeyProvider {
|
|
32
42
|
private readonly client;
|
|
33
43
|
private readonly version;
|
|
@@ -36,6 +46,32 @@ declare class GcpCloudKmsKeyProvider implements KeyProvider {
|
|
|
36
46
|
private readonly signing;
|
|
37
47
|
private activating;
|
|
38
48
|
private constructor();
|
|
49
|
+
/**
|
|
50
|
+
* Creates one version under an existing ASYMMETRIC_SIGN CryptoKey with a
|
|
51
|
+
* SOFTWARE EC_SIGN_ED25519 template, without opening any prior version.
|
|
52
|
+
* Returns a locally pending provider and immutable reference; activate(kid)
|
|
53
|
+
* explicitly before initial manager injection. Never provisions the parent,
|
|
54
|
+
* writes files, deletes keys, or closes the caller-owned client.
|
|
55
|
+
* Pending generation polls the same version at most 20 times, 250ms apart.
|
|
56
|
+
* Each transport call uses the caller's client timeout configuration.
|
|
57
|
+
* Failed/indeterminate creation may leave an operator-owned remote version;
|
|
58
|
+
* do not blindly retry. Normal load/configuration remains open-only.
|
|
59
|
+
*/
|
|
60
|
+
static create(client: GcpCloudKmsClient, config: {
|
|
61
|
+
parent: string;
|
|
62
|
+
algorithm: string;
|
|
63
|
+
}): Promise<{
|
|
64
|
+
provider: GcpCloudKmsKeyProvider;
|
|
65
|
+
kid: string;
|
|
66
|
+
keyRef: string;
|
|
67
|
+
}>;
|
|
68
|
+
/**
|
|
69
|
+
* Opens the selected active version and, optionally, an application-saved pending
|
|
70
|
+
* version for recovery. Both bindings are validated; the pending key supports
|
|
71
|
+
* JWK lookup and rotation proof signing but is not the active signer or live
|
|
72
|
+
* inventory. No discovery, generation, or activation occurs. Applications own
|
|
73
|
+
* durable references and recovery checks; activate performs the local transition.
|
|
74
|
+
*/
|
|
39
75
|
static load(client: GcpCloudKmsClient | undefined, config: GcpCloudKmsConfig): Promise<GcpCloudKmsKeyProvider>;
|
|
40
76
|
signingKey(): Promise<DnsIdJWK>;
|
|
41
77
|
jwk(kid: string): Promise<DnsIdJWK>;
|
|
@@ -49,8 +85,16 @@ declare class GcpCloudKmsKeyProvider implements KeyProvider {
|
|
|
49
85
|
signKey(kid: string, payload: Uint8Array): Promise<Uint8Array>;
|
|
50
86
|
private signVersion;
|
|
51
87
|
validateKeyGeneration(algorithm: string): Promise<void>;
|
|
52
|
-
/**
|
|
88
|
+
/**
|
|
89
|
+
* Explicit operator generation only; defaults to EdDSA and rejects other algorithms before creation.
|
|
90
|
+
* Pending generation polls the exact created version at most 20 times, 250ms apart,
|
|
91
|
+
* using the caller's transport timeouts, just as initial creation does.
|
|
92
|
+
* Returns a locally pending key without changing the active signer. Failures after
|
|
93
|
+
* creation retain the version reference and cause, without retrying or deleting it.
|
|
94
|
+
* Service/integrity failures are not caller-argument errors. Never called by configuration opening.
|
|
95
|
+
*/
|
|
53
96
|
generateKey(algorithm?: string): Promise<string>;
|
|
97
|
+
private generatePendingKey;
|
|
54
98
|
activate(kid: string): Promise<void>;
|
|
55
99
|
/**
|
|
56
100
|
* Removes local signing eligibility from an active, pending, or already
|
package/dist/index.js
CHANGED
|
@@ -5,8 +5,10 @@ var GcpCloudKmsKeyProvider = class _GcpCloudKmsKeyProvider {
|
|
|
5
5
|
constructor(client, version, publicKey) {
|
|
6
6
|
this.client = client;
|
|
7
7
|
this.version = version;
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
if (publicKey) {
|
|
9
|
+
this.activeKid = publicKey.kid;
|
|
10
|
+
this.keys.set(publicKey.kid, { version, jwk: publicKey, state: "active" });
|
|
11
|
+
}
|
|
10
12
|
}
|
|
11
13
|
client;
|
|
12
14
|
version;
|
|
@@ -14,10 +16,46 @@ var GcpCloudKmsKeyProvider = class _GcpCloudKmsKeyProvider {
|
|
|
14
16
|
activeKid;
|
|
15
17
|
signing = /* @__PURE__ */ new Set();
|
|
16
18
|
activating = false;
|
|
19
|
+
/**
|
|
20
|
+
* Creates one version under an existing ASYMMETRIC_SIGN CryptoKey with a
|
|
21
|
+
* SOFTWARE EC_SIGN_ED25519 template, without opening any prior version.
|
|
22
|
+
* Returns a locally pending provider and immutable reference; activate(kid)
|
|
23
|
+
* explicitly before initial manager injection. Never provisions the parent,
|
|
24
|
+
* writes files, deletes keys, or closes the caller-owned client.
|
|
25
|
+
* Pending generation polls the same version at most 20 times, 250ms apart.
|
|
26
|
+
* Each transport call uses the caller's client timeout configuration.
|
|
27
|
+
* Failed/indeterminate creation may leave an operator-owned remote version;
|
|
28
|
+
* do not blindly retry. Normal load/configuration remains open-only.
|
|
29
|
+
*/
|
|
30
|
+
static async create(client, config) {
|
|
31
|
+
if (config.algorithm !== "EC_SIGN_ED25519") throw new ArgumentError("Google Cloud KMS algorithm must be EC_SIGN_ED25519");
|
|
32
|
+
if (typeof config.parent !== "string" || !/^projects\/[A-Za-z0-9._:-]+\/locations\/[A-Za-z0-9_-]+\/keyRings\/[A-Za-z0-9_-]+\/cryptoKeys\/[A-Za-z0-9_-]+$/.test(config.parent)) {
|
|
33
|
+
throw new ArgumentError("Google Cloud KMS creation requires a CryptoKey parent");
|
|
34
|
+
}
|
|
35
|
+
if (!client.getCryptoKey || !client.createCryptoKeyVersion) throw new ArgumentError("Google Cloud KMS client does not support initial creation");
|
|
36
|
+
const [raw] = await client.getCryptoKey({ name: config.parent });
|
|
37
|
+
const parent = raw;
|
|
38
|
+
if (parent?.name !== config.parent || parent.purpose !== "ASYMMETRIC_SIGN" && parent.purpose !== 5 || !ed25519Software(parent.versionTemplate)) {
|
|
39
|
+
throw new ArgumentError("Google Cloud KMS requires a compatible signing parent/template");
|
|
40
|
+
}
|
|
41
|
+
const provider = new _GcpCloudKmsKeyProvider(client, config.parent);
|
|
42
|
+
const kid = await provider.generatePendingKey(void 0);
|
|
43
|
+
return { provider, kid, keyRef: provider.keys.get(kid).version };
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Opens the selected active version and, optionally, an application-saved pending
|
|
47
|
+
* version for recovery. Both bindings are validated; the pending key supports
|
|
48
|
+
* JWK lookup and rotation proof signing but is not the active signer or live
|
|
49
|
+
* inventory. No discovery, generation, or activation occurs. Applications own
|
|
50
|
+
* durable references and recovery checks; activate performs the local transition.
|
|
51
|
+
*/
|
|
17
52
|
static async load(client, config) {
|
|
18
53
|
const version = config.activeKeyVersion;
|
|
19
|
-
|
|
20
|
-
|
|
54
|
+
validateVersion(version);
|
|
55
|
+
const pendingVersion = config.pendingKeyVersion;
|
|
56
|
+
if (pendingVersion !== void 0) {
|
|
57
|
+
validateVersion(pendingVersion);
|
|
58
|
+
if (pendingVersion === version) throw new ArgumentError("Google Cloud KMS active and pending versions must differ");
|
|
21
59
|
}
|
|
22
60
|
if (config.algorithm !== "EC_SIGN_ED25519") throw new ArgumentError("Google Cloud KMS algorithm must be EC_SIGN_ED25519");
|
|
23
61
|
if (config.retainedKeyVersions?.length) throw new ArgumentError("Google Cloud KMS retained key loading is not supported");
|
|
@@ -25,26 +63,12 @@ var GcpCloudKmsKeyProvider = class _GcpCloudKmsKeyProvider {
|
|
|
25
63
|
const { KeyManagementServiceClient } = await import("@google-cloud/kms");
|
|
26
64
|
client = new KeyManagementServiceClient();
|
|
27
65
|
}
|
|
28
|
-
const
|
|
29
|
-
const
|
|
30
|
-
if (
|
|
31
|
-
|
|
32
|
-
if (
|
|
33
|
-
|
|
34
|
-
throw new ArgumentError("Google Cloud KMS public PEM checksum mismatch");
|
|
35
|
-
}
|
|
36
|
-
let publicKey;
|
|
37
|
-
try {
|
|
38
|
-
if (!response.pem.startsWith("-----BEGIN PUBLIC KEY-----")) throw new Error();
|
|
39
|
-
const key = createPublicKey({ key: response.pem, format: "pem", type: "spki" });
|
|
40
|
-
if (key.asymmetricKeyType !== "ed25519") throw new Error();
|
|
41
|
-
const exported = key.export({ format: "jwk" });
|
|
42
|
-
publicKey = { kty: "OKP", crv: "Ed25519", x: exported.x, kid: "", alg: "EdDSA", use: "sig" };
|
|
43
|
-
} catch {
|
|
44
|
-
throw new ArgumentError("Google Cloud KMS returned invalid Ed25519 public SPKI");
|
|
45
|
-
}
|
|
46
|
-
publicKey.kid = await jwkThumbprint(publicKey);
|
|
47
|
-
return new _GcpCloudKmsKeyProvider(client, version, Object.freeze(publicKey));
|
|
66
|
+
const publicKey = await loadPublicKey(client, version);
|
|
67
|
+
const pendingKey = pendingVersion === void 0 ? void 0 : await loadPublicKey(client, pendingVersion);
|
|
68
|
+
if (pendingKey?.kid === publicKey.kid) throw new ArgumentError("Google Cloud KMS pending version has duplicate public key");
|
|
69
|
+
const provider = new _GcpCloudKmsKeyProvider(client, version, publicKey);
|
|
70
|
+
if (pendingKey) provider.keys.set(pendingKey.kid, { version: pendingVersion, jwk: pendingKey, state: "pending" });
|
|
71
|
+
return provider;
|
|
48
72
|
}
|
|
49
73
|
async signingKey() {
|
|
50
74
|
if (!this.activeKid) throw new ArgumentError("Google Cloud KMS has no active key");
|
|
@@ -93,21 +117,46 @@ var GcpCloudKmsKeyProvider = class _GcpCloudKmsKeyProvider {
|
|
|
93
117
|
async validateKeyGeneration(algorithm) {
|
|
94
118
|
if (algorithm !== "EdDSA") throw new ArgumentError(`Google Cloud KMS generation settings do not support ${algorithm}`);
|
|
95
119
|
}
|
|
96
|
-
/**
|
|
120
|
+
/**
|
|
121
|
+
* Explicit operator generation only; defaults to EdDSA and rejects other algorithms before creation.
|
|
122
|
+
* Pending generation polls the exact created version at most 20 times, 250ms apart,
|
|
123
|
+
* using the caller's transport timeouts, just as initial creation does.
|
|
124
|
+
* Returns a locally pending key without changing the active signer. Failures after
|
|
125
|
+
* creation retain the version reference and cause, without retrying or deleting it.
|
|
126
|
+
* Service/integrity failures are not caller-argument errors. Never called by configuration opening.
|
|
127
|
+
*/
|
|
97
128
|
async generateKey(algorithm) {
|
|
129
|
+
return this.generatePendingKey(algorithm);
|
|
130
|
+
}
|
|
131
|
+
async generatePendingKey(algorithm) {
|
|
98
132
|
await this.validateKeyGeneration(algorithm ?? "EdDSA");
|
|
99
133
|
if (!this.client.createCryptoKeyVersion) throw new ArgumentError("Google Cloud KMS client does not support version creation");
|
|
100
|
-
const parent = this.version.slice(0, this.version.lastIndexOf("/cryptoKeyVersions/"));
|
|
134
|
+
const parent = this.version.includes("/cryptoKeyVersions/") ? this.version.slice(0, this.version.lastIndexOf("/cryptoKeyVersions/")) : this.version;
|
|
101
135
|
const [raw] = await this.client.createCryptoKeyVersion({ parent, cryptoKeyVersion: { state: "ENABLED" } });
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
136
|
+
let created = raw;
|
|
137
|
+
const name = created?.name;
|
|
138
|
+
if (typeof name !== "string" || !name.startsWith(parent + "/cryptoKeyVersions/") || !/^[1-9][0-9]*$/.test(name.slice((parent + "/cryptoKeyVersions/").length))) {
|
|
139
|
+
throw new ArgumentError(`Google Cloud KMS created an unexpected key version${typeof name === "string" && name ? `: ${name}` : ""}`);
|
|
140
|
+
}
|
|
141
|
+
try {
|
|
142
|
+
for (let poll = 0; ; poll++) {
|
|
143
|
+
if (created?.name !== name || !ed25519Software(created)) throw new ArgumentError("Google Cloud KMS created an unexpected key version");
|
|
144
|
+
if (created.state === "ENABLED" || created.state === 1) break;
|
|
145
|
+
if (created.state !== "PENDING_GENERATION" && created.state !== 5 || poll >= 20 || !this.client.getCryptoKeyVersion) {
|
|
146
|
+
throw new ArgumentError("Google Cloud KMS version is not ready for signing");
|
|
147
|
+
}
|
|
148
|
+
await new Promise((resolve) => setTimeout(resolve, 250));
|
|
149
|
+
const [metadata] = await this.client.getCryptoKeyVersion({ name });
|
|
150
|
+
created = metadata;
|
|
151
|
+
}
|
|
152
|
+
const pending = await _GcpCloudKmsKeyProvider.load(this.client, { activeKeyVersion: name, algorithm: "EC_SIGN_ED25519" });
|
|
153
|
+
const jwk = await pending.signingKey();
|
|
154
|
+
if (this.keys.has(jwk.kid)) throw new ArgumentError("Google Cloud KMS generated duplicate public key");
|
|
155
|
+
this.keys.set(jwk.kid, { version: name, jwk: Object.freeze(jwk), state: "pending" });
|
|
156
|
+
return jwk.kid;
|
|
157
|
+
} catch (cause) {
|
|
158
|
+
throw new Error(`Google Cloud KMS created version ${name}: ${cause instanceof Error ? cause.message : String(cause)}`, { cause });
|
|
105
159
|
}
|
|
106
|
-
const pending = await _GcpCloudKmsKeyProvider.load(this.client, { activeKeyVersion: created.name, algorithm: "EC_SIGN_ED25519" });
|
|
107
|
-
const jwk = await pending.signingKey();
|
|
108
|
-
if (this.keys.has(jwk.kid)) throw new ArgumentError("Google Cloud KMS generated duplicate public key");
|
|
109
|
-
this.keys.set(jwk.kid, { version: created.name, jwk: Object.freeze(jwk), state: "pending" });
|
|
110
|
-
return jwk.kid;
|
|
111
160
|
}
|
|
112
161
|
async activate(kid) {
|
|
113
162
|
if (this.activating) throw new ArgumentError("Google Cloud KMS activation is already in progress");
|
|
@@ -142,6 +191,33 @@ var GcpCloudKmsKeyProvider = class _GcpCloudKmsKeyProvider {
|
|
|
142
191
|
return this.supersede(kid);
|
|
143
192
|
}
|
|
144
193
|
};
|
|
194
|
+
function validateVersion(version) {
|
|
195
|
+
if (typeof version !== "string" || !/^projects\/[A-Za-z0-9._:-]+\/locations\/[A-Za-z0-9_-]+\/keyRings\/[A-Za-z0-9_-]+\/cryptoKeys\/[A-Za-z0-9_-]+\/cryptoKeyVersions\/[1-9][0-9]*$/.test(version)) {
|
|
196
|
+
throw new ArgumentError("Google Cloud KMS requires an immutable CryptoKeyVersion name");
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
async function loadPublicKey(client, version) {
|
|
200
|
+
const [raw] = await client.getPublicKey({ name: version });
|
|
201
|
+
const response = raw;
|
|
202
|
+
if (response?.name !== version) throw new ArgumentError("Google Cloud KMS public key version mismatch");
|
|
203
|
+
if (response.algorithm !== "EC_SIGN_ED25519" && response.algorithm !== 40) throw new ArgumentError("Google Cloud KMS public key algorithm mismatch");
|
|
204
|
+
if (response.protectionLevel !== "SOFTWARE" && response.protectionLevel !== 1) throw new ArgumentError("Google Cloud KMS public key must use SOFTWARE protection");
|
|
205
|
+
if (typeof response.pem !== "string" || !checksumMatches(Buffer.from(response.pem), response.pemCrc32c)) {
|
|
206
|
+
throw new ArgumentError("Google Cloud KMS public PEM checksum mismatch");
|
|
207
|
+
}
|
|
208
|
+
let publicKey;
|
|
209
|
+
try {
|
|
210
|
+
if (!response.pem.startsWith("-----BEGIN PUBLIC KEY-----")) throw new Error();
|
|
211
|
+
const key = createPublicKey({ key: response.pem, format: "pem", type: "spki" });
|
|
212
|
+
if (key.asymmetricKeyType !== "ed25519") throw new Error();
|
|
213
|
+
const exported = key.export({ format: "jwk" });
|
|
214
|
+
publicKey = { kty: "OKP", crv: "Ed25519", x: exported.x, kid: "", alg: "EdDSA", use: "sig" };
|
|
215
|
+
} catch {
|
|
216
|
+
throw new ArgumentError("Google Cloud KMS returned invalid Ed25519 public SPKI");
|
|
217
|
+
}
|
|
218
|
+
publicKey.kid = await jwkThumbprint(publicKey);
|
|
219
|
+
return Object.freeze(publicKey);
|
|
220
|
+
}
|
|
145
221
|
function checksumMatches(bytes, checksum) {
|
|
146
222
|
const raw = checksum?.value;
|
|
147
223
|
if (raw === void 0 || raw === null) return false;
|
|
@@ -158,6 +234,9 @@ function crc32c(bytes) {
|
|
|
158
234
|
}
|
|
159
235
|
return (crc ^ 4294967295) >>> 0;
|
|
160
236
|
}
|
|
237
|
+
function ed25519Software(value) {
|
|
238
|
+
return !!value && (value.algorithm === "EC_SIGN_ED25519" || value.algorithm === 40) && (value.protectionLevel === "SOFTWARE" || value.protectionLevel === 1);
|
|
239
|
+
}
|
|
161
240
|
export {
|
|
162
241
|
GcpCloudKmsKeyProvider
|
|
163
242
|
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dnsid-ai/key-gcp",
|
|
3
3
|
"author": "Known Systems AI, Inc.",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.36.0",
|
|
5
5
|
"description": "DNSid Google Cloud KMS Ed25519 key provider integration.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"prepack": "node ../../scripts/copy-notice.mjs"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@dnsid-ai/protocol": "^0.
|
|
43
|
+
"@dnsid-ai/protocol": "^0.36.0",
|
|
44
44
|
"@google-cloud/kms": "^6.3.0"
|
|
45
45
|
},
|
|
46
46
|
"license": "Apache-2.0",
|