@layervai/qurl-aws 2.0.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.
@@ -0,0 +1,3 @@
1
+ export { createSSMAgentStateStore } from "./ssm.js";
2
+ export { createSecretsManagerAgentStateStore } from "./secrets-manager.js";
3
+ export { createKMSAgentStateKeyWrapper } from "./kms.js";
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createKMSAgentStateKeyWrapper = exports.createSecretsManagerAgentStateStore = exports.createSSMAgentStateStore = void 0;
4
+ var ssm_js_1 = require("./ssm.js");
5
+ Object.defineProperty(exports, "createSSMAgentStateStore", { enumerable: true, get: function () { return ssm_js_1.createSSMAgentStateStore; } });
6
+ var secrets_manager_js_1 = require("./secrets-manager.js");
7
+ Object.defineProperty(exports, "createSecretsManagerAgentStateStore", { enumerable: true, get: function () { return secrets_manager_js_1.createSecretsManagerAgentStateStore; } });
8
+ var kms_js_1 = require("./kms.js");
9
+ Object.defineProperty(exports, "createKMSAgentStateKeyWrapper", { enumerable: true, get: function () { return kms_js_1.createKMSAgentStateKeyWrapper; } });
@@ -0,0 +1,3 @@
1
+ import { type KMSClient } from "@aws-sdk/client-kms";
2
+ import { type AgentStateKeyWrapper } from "@layervai/qurl/node";
3
+ export declare function createKMSAgentStateKeyWrapper(client: KMSClient, keyID: string): AgentStateKeyWrapper;
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createKMSAgentStateKeyWrapper = createKMSAgentStateKeyWrapper;
4
+ const client_kms_1 = require("@aws-sdk/client-kms");
5
+ const node_1 = require("@layervai/qurl/node");
6
+ const store_js_1 = require("./store.js");
7
+ const KEY_ARN = /^arn:aws(?:-[a-z]+)?:kms:[a-z0-9-]+:\d{12}:key\/(?:[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}|mrk-[0-9a-f]{32})$/;
8
+ function context(binding) {
9
+ if (binding.purpose !== "qurl-go/agent-state" ||
10
+ binding.envelopeVersion !== 1 ||
11
+ !binding.agentID ||
12
+ !binding.providerID)
13
+ throw new node_1.AgentStateError("INVALID_KEY_BINDING");
14
+ return {
15
+ qurl_purpose: binding.purpose,
16
+ qurl_envelope_version: String(binding.envelopeVersion),
17
+ qurl_provider_id: binding.providerID,
18
+ qurl_agent_id: binding.agentID,
19
+ };
20
+ }
21
+ function createKMSAgentStateKeyWrapper(client, keyID) {
22
+ if (!client || !keyID || keyID.trim() !== keyID || keyID.length > 2048)
23
+ throw new node_1.AgentStateError("INVALID_KMS_CONFIGURATION");
24
+ return {
25
+ async wrapKey(key, binding, signal) {
26
+ signal?.throwIfAborted();
27
+ if (key.length !== 32)
28
+ throw new node_1.AgentStateError("INVALID_DATA_KEY");
29
+ const plaintext = Buffer.from(key);
30
+ try {
31
+ const result = await client.send(new client_kms_1.EncryptCommand({
32
+ KeyId: keyID,
33
+ Plaintext: plaintext,
34
+ EncryptionAlgorithm: "SYMMETRIC_DEFAULT",
35
+ EncryptionContext: context(binding),
36
+ }), { abortSignal: signal });
37
+ if (!result.CiphertextBlob?.length || !result.KeyId || !KEY_ARN.test(result.KeyId))
38
+ throw new node_1.AgentStateError("INVALID_KMS_RESPONSE");
39
+ return {
40
+ version: 1,
41
+ ciphertext: Buffer.from(result.CiphertextBlob),
42
+ metadata: { key_id: result.KeyId },
43
+ };
44
+ }
45
+ finally {
46
+ plaintext.fill(0);
47
+ }
48
+ },
49
+ async unwrapKey(wrapped, binding, signal) {
50
+ signal?.throwIfAborted();
51
+ const metadata = wrapped.metadata;
52
+ if (wrapped.version !== 1 ||
53
+ !wrapped.ciphertext.length ||
54
+ !metadata ||
55
+ typeof metadata !== "object" ||
56
+ Array.isArray(metadata) ||
57
+ Object.keys(metadata).length !== 1 ||
58
+ typeof metadata.key_id !== "string" ||
59
+ !KEY_ARN.test(metadata.key_id))
60
+ throw new node_1.AgentStateError("INVALID_WRAPPED_KEY");
61
+ let result;
62
+ try {
63
+ result = await client.send(new client_kms_1.DecryptCommand({
64
+ KeyId: metadata.key_id,
65
+ CiphertextBlob: wrapped.ciphertext,
66
+ EncryptionAlgorithm: "SYMMETRIC_DEFAULT",
67
+ EncryptionContext: context(binding),
68
+ }), { abortSignal: signal });
69
+ }
70
+ catch (error) {
71
+ if ((0, store_js_1.errorNamed)(error, "InvalidCiphertextException") ||
72
+ (0, store_js_1.errorNamed)(error, "IncorrectKeyException"))
73
+ throw new node_1.AgentStateError("INVALID_WRAPPED_KEY");
74
+ throw error;
75
+ }
76
+ try {
77
+ if (result.KeyId !== metadata.key_id || result.Plaintext?.length !== 32)
78
+ throw new node_1.AgentStateError("INVALID_KMS_RESPONSE");
79
+ return Buffer.from(result.Plaintext);
80
+ }
81
+ finally {
82
+ result.Plaintext?.fill(0);
83
+ }
84
+ },
85
+ };
86
+ }
@@ -0,0 +1 @@
1
+ {"type":"commonjs"}
@@ -0,0 +1,3 @@
1
+ import { type SecretsManagerClient } from "@aws-sdk/client-secrets-manager";
2
+ import { type AgentStateStore } from "@layervai/qurl/node";
3
+ export declare function createSecretsManagerAgentStateStore(client: SecretsManagerClient, secretID: string, kmsKeyID?: string): AgentStateStore;
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createSecretsManagerAgentStateStore = createSecretsManagerAgentStateStore;
4
+ const client_secrets_manager_1 = require("@aws-sdk/client-secrets-manager");
5
+ const node_1 = require("@layervai/qurl/node");
6
+ const store_js_1 = require("./store.js");
7
+ const node_crypto_1 = require("node:crypto");
8
+ function createSecretsManagerAgentStateStore(client, secretID, kmsKeyID) {
9
+ secretID = secretID.trim();
10
+ if (!client || !secretID)
11
+ throw new node_1.AgentStateError("INVALID_SECRETS_MANAGER_CONFIGURATION");
12
+ return (0, store_js_1.lockedStore)({
13
+ async load(signal) {
14
+ signal?.throwIfAborted();
15
+ let result;
16
+ try {
17
+ result = await client.send(new client_secrets_manager_1.GetSecretValueCommand({ SecretId: secretID }), {
18
+ abortSignal: signal,
19
+ });
20
+ }
21
+ catch (error) {
22
+ if ((0, store_js_1.errorNamed)(error, "ResourceNotFoundException"))
23
+ throw new node_1.AgentStateError("NOT_FOUND");
24
+ throw error;
25
+ }
26
+ if (typeof result.SecretString !== "string")
27
+ throw new node_1.AgentStateError("INVALID_STATE");
28
+ const raw = Buffer.from(result.SecretString);
29
+ try {
30
+ return (0, node_1.decodeAgentState)(raw);
31
+ }
32
+ finally {
33
+ raw.fill(0);
34
+ }
35
+ },
36
+ async save(state, signal) {
37
+ signal?.throwIfAborted();
38
+ const raw = (0, node_1.encodeAgentState)(state);
39
+ const token = (0, node_crypto_1.randomUUID)();
40
+ try {
41
+ if (raw.length > 65536)
42
+ throw new node_1.AgentStateError("SECRETS_MANAGER_SIZE_LIMIT");
43
+ const SecretString = raw.toString();
44
+ try {
45
+ await client.send(new client_secrets_manager_1.PutSecretValueCommand({
46
+ SecretId: secretID,
47
+ SecretString,
48
+ ClientRequestToken: token,
49
+ }), { abortSignal: signal });
50
+ }
51
+ catch (error) {
52
+ if (!(0, store_js_1.errorNamed)(error, "ResourceNotFoundException"))
53
+ throw error;
54
+ if (secretID.startsWith("arn:"))
55
+ throw new node_1.AgentStateError("SECRET_MUST_EXIST");
56
+ try {
57
+ await client.send(new client_secrets_manager_1.CreateSecretCommand({
58
+ Name: secretID,
59
+ SecretString,
60
+ ClientRequestToken: token,
61
+ KmsKeyId: kmsKeyID,
62
+ }), { abortSignal: signal });
63
+ }
64
+ catch (creation) {
65
+ if (!(0, store_js_1.errorNamed)(creation, "ResourceExistsException"))
66
+ throw creation;
67
+ await client.send(new client_secrets_manager_1.PutSecretValueCommand({
68
+ SecretId: secretID,
69
+ SecretString,
70
+ ClientRequestToken: token,
71
+ }), { abortSignal: signal });
72
+ }
73
+ }
74
+ }
75
+ finally {
76
+ raw.fill(0);
77
+ }
78
+ },
79
+ });
80
+ }
@@ -0,0 +1,6 @@
1
+ import { type SSMClient } from "@aws-sdk/client-ssm";
2
+ import { type AgentStateStore } from "@layervai/qurl/node";
3
+ export declare function createSSMAgentStateStore(client: SSMClient, name: string, options?: {
4
+ kmsKeyID?: string;
5
+ tier?: "Standard" | "Advanced" | "Intelligent-Tiering";
6
+ }): AgentStateStore;
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createSSMAgentStateStore = createSSMAgentStateStore;
4
+ const client_ssm_1 = require("@aws-sdk/client-ssm");
5
+ const node_1 = require("@layervai/qurl/node");
6
+ const store_js_1 = require("./store.js");
7
+ function createSSMAgentStateStore(client, name, options = {}) {
8
+ name = name.trim();
9
+ if (!client || !name)
10
+ throw new node_1.AgentStateError("INVALID_SSM_CONFIGURATION");
11
+ const { kmsKeyID, tier } = options;
12
+ return (0, store_js_1.lockedStore)({
13
+ async load(signal) {
14
+ signal?.throwIfAborted();
15
+ let result;
16
+ try {
17
+ result = await client.send(new client_ssm_1.GetParameterCommand({ Name: name, WithDecryption: true }), {
18
+ abortSignal: signal,
19
+ });
20
+ }
21
+ catch (error) {
22
+ if ((0, store_js_1.errorNamed)(error, "ParameterNotFound"))
23
+ throw new node_1.AgentStateError("NOT_FOUND");
24
+ throw error;
25
+ }
26
+ if (typeof result.Parameter?.Value !== "string")
27
+ throw new node_1.AgentStateError("INVALID_STATE");
28
+ const raw = Buffer.from(result.Parameter.Value);
29
+ try {
30
+ return (0, node_1.decodeAgentState)(raw);
31
+ }
32
+ finally {
33
+ raw.fill(0);
34
+ }
35
+ },
36
+ async save(state, signal) {
37
+ signal?.throwIfAborted();
38
+ const raw = (0, node_1.encodeAgentState)(state);
39
+ try {
40
+ if (raw.length > (tier === "Advanced" || tier === "Intelligent-Tiering" ? 8192 : 4096))
41
+ throw new node_1.AgentStateError("SSM_SIZE_LIMIT");
42
+ await client.send(new client_ssm_1.PutParameterCommand({
43
+ Name: name,
44
+ Value: raw.toString(),
45
+ Type: "SecureString",
46
+ Overwrite: true,
47
+ KeyId: kmsKeyID,
48
+ Tier: tier,
49
+ }), { abortSignal: signal });
50
+ }
51
+ finally {
52
+ raw.fill(0);
53
+ }
54
+ },
55
+ });
56
+ }
@@ -0,0 +1,4 @@
1
+ import type { AgentStateStore } from "@layervai/qurl/node";
2
+ /** SSM and Secrets Manager have no transaction lock. One process must own each agent state. */
3
+ export declare function lockedStore(store: Omit<AgentStateStore, "withLock">): AgentStateStore;
4
+ export declare function errorNamed(error: unknown, name: string): boolean;
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.lockedStore = lockedStore;
4
+ exports.errorNamed = errorNamed;
5
+ /** SSM and Secrets Manager have no transaction lock. One process must own each agent state. */
6
+ function lockedStore(store) {
7
+ let tail = Promise.resolve();
8
+ const result = {
9
+ ...store,
10
+ save(state, signal) {
11
+ const snapshot = structuredClone(state);
12
+ return result.withLock((locked) => locked.save(snapshot, signal), signal);
13
+ },
14
+ async withLock(operation, signal) {
15
+ let release;
16
+ const previous = tail;
17
+ tail = new Promise((resolve) => {
18
+ release = resolve;
19
+ });
20
+ let entered = false;
21
+ let abort;
22
+ try {
23
+ if (signal) {
24
+ await Promise.race([
25
+ previous,
26
+ new Promise((_, reject) => {
27
+ abort = () => reject(signal.reason);
28
+ signal.addEventListener("abort", abort, { once: true });
29
+ if (signal.aborted)
30
+ abort();
31
+ }),
32
+ ]);
33
+ }
34
+ else
35
+ await previous;
36
+ entered = true;
37
+ signal?.throwIfAborted();
38
+ let active = true;
39
+ const check = () => {
40
+ if (!active)
41
+ throw new Error("qURL AWS state lock has expired");
42
+ };
43
+ const scoped = {
44
+ load: async (nextSignal) => {
45
+ check();
46
+ const effective = nextSignal ?? signal;
47
+ effective?.throwIfAborted();
48
+ const state = await store.load(effective);
49
+ check();
50
+ effective?.throwIfAborted();
51
+ return state;
52
+ },
53
+ save: async (state, nextSignal) => {
54
+ check();
55
+ const effective = nextSignal ?? signal;
56
+ effective?.throwIfAborted();
57
+ return store.save(state, effective);
58
+ },
59
+ withLock: async (operation) => {
60
+ check();
61
+ return operation(scoped);
62
+ },
63
+ };
64
+ try {
65
+ return await operation(scoped);
66
+ }
67
+ finally {
68
+ active = false;
69
+ }
70
+ }
71
+ finally {
72
+ if (abort)
73
+ signal?.removeEventListener("abort", abort);
74
+ if (entered)
75
+ release();
76
+ else
77
+ void previous.then(release);
78
+ }
79
+ },
80
+ };
81
+ return result;
82
+ }
83
+ function errorNamed(error, name) {
84
+ return error instanceof Error && error.name === name;
85
+ }
@@ -0,0 +1,4 @@
1
+ export { createSSMAgentStateStore } from "./ssm.js";
2
+ export { createSecretsManagerAgentStateStore } from "./secrets-manager.js";
3
+ export { createKMSAgentStateKeyWrapper } from "./kms.js";
4
+ //# 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,wBAAwB,EAAE,MAAM,UAAU,CAAC;AACpD,OAAO,EAAE,mCAAmC,EAAE,MAAM,sBAAsB,CAAC;AAC3E,OAAO,EAAE,6BAA6B,EAAE,MAAM,UAAU,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { createSSMAgentStateStore } from "./ssm.js";
2
+ export { createSecretsManagerAgentStateStore } from "./secrets-manager.js";
3
+ export { createKMSAgentStateKeyWrapper } from "./kms.js";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,UAAU,CAAC;AACpD,OAAO,EAAE,mCAAmC,EAAE,MAAM,sBAAsB,CAAC;AAC3E,OAAO,EAAE,6BAA6B,EAAE,MAAM,UAAU,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { type KMSClient } from "@aws-sdk/client-kms";
2
+ import { type AgentStateKeyWrapper } from "@layervai/qurl/node";
3
+ export declare function createKMSAgentStateKeyWrapper(client: KMSClient, keyID: string): AgentStateKeyWrapper;
4
+ //# sourceMappingURL=kms.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kms.d.ts","sourceRoot":"","sources":["../../src/kms.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkC,KAAK,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACrF,OAAO,EAGL,KAAK,oBAAoB,EAC1B,MAAM,qBAAqB,CAAC;AAqB7B,wBAAgB,6BAA6B,CAC3C,MAAM,EAAE,SAAS,EACjB,KAAK,EAAE,MAAM,GACZ,oBAAoB,CAuEtB"}
@@ -0,0 +1,84 @@
1
+ import { EncryptCommand, DecryptCommand } from "@aws-sdk/client-kms";
2
+ import { AgentStateError, } from "@layervai/qurl/node";
3
+ import { errorNamed } from "./store.js";
4
+ const KEY_ARN = /^arn:aws(?:-[a-z]+)?:kms:[a-z0-9-]+:\d{12}:key\/(?:[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}|mrk-[0-9a-f]{32})$/;
5
+ function context(binding) {
6
+ if (binding.purpose !== "qurl-go/agent-state" ||
7
+ binding.envelopeVersion !== 1 ||
8
+ !binding.agentID ||
9
+ !binding.providerID)
10
+ throw new AgentStateError("INVALID_KEY_BINDING");
11
+ return {
12
+ qurl_purpose: binding.purpose,
13
+ qurl_envelope_version: String(binding.envelopeVersion),
14
+ qurl_provider_id: binding.providerID,
15
+ qurl_agent_id: binding.agentID,
16
+ };
17
+ }
18
+ export function createKMSAgentStateKeyWrapper(client, keyID) {
19
+ if (!client || !keyID || keyID.trim() !== keyID || keyID.length > 2048)
20
+ throw new AgentStateError("INVALID_KMS_CONFIGURATION");
21
+ return {
22
+ async wrapKey(key, binding, signal) {
23
+ signal?.throwIfAborted();
24
+ if (key.length !== 32)
25
+ throw new AgentStateError("INVALID_DATA_KEY");
26
+ const plaintext = Buffer.from(key);
27
+ try {
28
+ const result = await client.send(new EncryptCommand({
29
+ KeyId: keyID,
30
+ Plaintext: plaintext,
31
+ EncryptionAlgorithm: "SYMMETRIC_DEFAULT",
32
+ EncryptionContext: context(binding),
33
+ }), { abortSignal: signal });
34
+ if (!result.CiphertextBlob?.length || !result.KeyId || !KEY_ARN.test(result.KeyId))
35
+ throw new AgentStateError("INVALID_KMS_RESPONSE");
36
+ return {
37
+ version: 1,
38
+ ciphertext: Buffer.from(result.CiphertextBlob),
39
+ metadata: { key_id: result.KeyId },
40
+ };
41
+ }
42
+ finally {
43
+ plaintext.fill(0);
44
+ }
45
+ },
46
+ async unwrapKey(wrapped, binding, signal) {
47
+ signal?.throwIfAborted();
48
+ const metadata = wrapped.metadata;
49
+ if (wrapped.version !== 1 ||
50
+ !wrapped.ciphertext.length ||
51
+ !metadata ||
52
+ typeof metadata !== "object" ||
53
+ Array.isArray(metadata) ||
54
+ Object.keys(metadata).length !== 1 ||
55
+ typeof metadata.key_id !== "string" ||
56
+ !KEY_ARN.test(metadata.key_id))
57
+ throw new AgentStateError("INVALID_WRAPPED_KEY");
58
+ let result;
59
+ try {
60
+ result = await client.send(new DecryptCommand({
61
+ KeyId: metadata.key_id,
62
+ CiphertextBlob: wrapped.ciphertext,
63
+ EncryptionAlgorithm: "SYMMETRIC_DEFAULT",
64
+ EncryptionContext: context(binding),
65
+ }), { abortSignal: signal });
66
+ }
67
+ catch (error) {
68
+ if (errorNamed(error, "InvalidCiphertextException") ||
69
+ errorNamed(error, "IncorrectKeyException"))
70
+ throw new AgentStateError("INVALID_WRAPPED_KEY");
71
+ throw error;
72
+ }
73
+ try {
74
+ if (result.KeyId !== metadata.key_id || result.Plaintext?.length !== 32)
75
+ throw new AgentStateError("INVALID_KMS_RESPONSE");
76
+ return Buffer.from(result.Plaintext);
77
+ }
78
+ finally {
79
+ result.Plaintext?.fill(0);
80
+ }
81
+ },
82
+ };
83
+ }
84
+ //# sourceMappingURL=kms.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kms.js","sourceRoot":"","sources":["../../src/kms.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { type SecretsManagerClient } from "@aws-sdk/client-secrets-manager";
2
+ import { type AgentStateStore } from "@layervai/qurl/node";
3
+ export declare function createSecretsManagerAgentStateStore(client: SecretsManagerClient, secretID: string, kmsKeyID?: string): AgentStateStore;
4
+ //# sourceMappingURL=secrets-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secrets-manager.d.ts","sourceRoot":"","sources":["../../src/secrets-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,oBAAoB,EAC1B,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAIL,KAAK,eAAe,EACrB,MAAM,qBAAqB,CAAC;AAI7B,wBAAgB,mCAAmC,CACjD,MAAM,EAAE,oBAAoB,EAC5B,QAAQ,EAAE,MAAM,EAChB,QAAQ,CAAC,EAAE,MAAM,GAChB,eAAe,CAqEjB"}
@@ -0,0 +1,78 @@
1
+ import { GetSecretValueCommand, PutSecretValueCommand, CreateSecretCommand, } from "@aws-sdk/client-secrets-manager";
2
+ import { AgentStateError, decodeAgentState, encodeAgentState, } from "@layervai/qurl/node";
3
+ import { lockedStore, errorNamed } from "./store.js";
4
+ import { randomUUID } from "node:crypto";
5
+ export function createSecretsManagerAgentStateStore(client, secretID, kmsKeyID) {
6
+ secretID = secretID.trim();
7
+ if (!client || !secretID)
8
+ throw new AgentStateError("INVALID_SECRETS_MANAGER_CONFIGURATION");
9
+ return lockedStore({
10
+ async load(signal) {
11
+ signal?.throwIfAborted();
12
+ let result;
13
+ try {
14
+ result = await client.send(new GetSecretValueCommand({ SecretId: secretID }), {
15
+ abortSignal: signal,
16
+ });
17
+ }
18
+ catch (error) {
19
+ if (errorNamed(error, "ResourceNotFoundException"))
20
+ throw new AgentStateError("NOT_FOUND");
21
+ throw error;
22
+ }
23
+ if (typeof result.SecretString !== "string")
24
+ throw new AgentStateError("INVALID_STATE");
25
+ const raw = Buffer.from(result.SecretString);
26
+ try {
27
+ return decodeAgentState(raw);
28
+ }
29
+ finally {
30
+ raw.fill(0);
31
+ }
32
+ },
33
+ async save(state, signal) {
34
+ signal?.throwIfAborted();
35
+ const raw = encodeAgentState(state);
36
+ const token = randomUUID();
37
+ try {
38
+ if (raw.length > 65536)
39
+ throw new AgentStateError("SECRETS_MANAGER_SIZE_LIMIT");
40
+ const SecretString = raw.toString();
41
+ try {
42
+ await client.send(new PutSecretValueCommand({
43
+ SecretId: secretID,
44
+ SecretString,
45
+ ClientRequestToken: token,
46
+ }), { abortSignal: signal });
47
+ }
48
+ catch (error) {
49
+ if (!errorNamed(error, "ResourceNotFoundException"))
50
+ throw error;
51
+ if (secretID.startsWith("arn:"))
52
+ throw new AgentStateError("SECRET_MUST_EXIST");
53
+ try {
54
+ await client.send(new CreateSecretCommand({
55
+ Name: secretID,
56
+ SecretString,
57
+ ClientRequestToken: token,
58
+ KmsKeyId: kmsKeyID,
59
+ }), { abortSignal: signal });
60
+ }
61
+ catch (creation) {
62
+ if (!errorNamed(creation, "ResourceExistsException"))
63
+ throw creation;
64
+ await client.send(new PutSecretValueCommand({
65
+ SecretId: secretID,
66
+ SecretString,
67
+ ClientRequestToken: token,
68
+ }), { abortSignal: signal });
69
+ }
70
+ }
71
+ }
72
+ finally {
73
+ raw.fill(0);
74
+ }
75
+ },
76
+ });
77
+ }
78
+ //# sourceMappingURL=secrets-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secrets-manager.js","sourceRoot":"","sources":["../../src/secrets-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import { type SSMClient } from "@aws-sdk/client-ssm";
2
+ import { type AgentStateStore } from "@layervai/qurl/node";
3
+ export declare function createSSMAgentStateStore(client: SSMClient, name: string, options?: {
4
+ kmsKeyID?: string;
5
+ tier?: "Standard" | "Advanced" | "Intelligent-Tiering";
6
+ }): AgentStateStore;
7
+ //# sourceMappingURL=ssm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ssm.d.ts","sourceRoot":"","sources":["../../src/ssm.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4C,KAAK,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAC/F,OAAO,EAIL,KAAK,eAAe,EACrB,MAAM,qBAAqB,CAAC;AAG7B,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,UAAU,GAAG,UAAU,GAAG,qBAAqB,CAAA;CAAO,GAC1F,eAAe,CA8CjB"}
@@ -0,0 +1,54 @@
1
+ import { GetParameterCommand, PutParameterCommand } from "@aws-sdk/client-ssm";
2
+ import { AgentStateError, decodeAgentState, encodeAgentState, } from "@layervai/qurl/node";
3
+ import { lockedStore, errorNamed } from "./store.js";
4
+ export function createSSMAgentStateStore(client, name, options = {}) {
5
+ name = name.trim();
6
+ if (!client || !name)
7
+ throw new AgentStateError("INVALID_SSM_CONFIGURATION");
8
+ const { kmsKeyID, tier } = options;
9
+ return lockedStore({
10
+ async load(signal) {
11
+ signal?.throwIfAborted();
12
+ let result;
13
+ try {
14
+ result = await client.send(new GetParameterCommand({ Name: name, WithDecryption: true }), {
15
+ abortSignal: signal,
16
+ });
17
+ }
18
+ catch (error) {
19
+ if (errorNamed(error, "ParameterNotFound"))
20
+ throw new AgentStateError("NOT_FOUND");
21
+ throw error;
22
+ }
23
+ if (typeof result.Parameter?.Value !== "string")
24
+ throw new AgentStateError("INVALID_STATE");
25
+ const raw = Buffer.from(result.Parameter.Value);
26
+ try {
27
+ return decodeAgentState(raw);
28
+ }
29
+ finally {
30
+ raw.fill(0);
31
+ }
32
+ },
33
+ async save(state, signal) {
34
+ signal?.throwIfAborted();
35
+ const raw = encodeAgentState(state);
36
+ try {
37
+ if (raw.length > (tier === "Advanced" || tier === "Intelligent-Tiering" ? 8192 : 4096))
38
+ throw new AgentStateError("SSM_SIZE_LIMIT");
39
+ await client.send(new PutParameterCommand({
40
+ Name: name,
41
+ Value: raw.toString(),
42
+ Type: "SecureString",
43
+ Overwrite: true,
44
+ KeyId: kmsKeyID,
45
+ Tier: tier,
46
+ }), { abortSignal: signal });
47
+ }
48
+ finally {
49
+ raw.fill(0);
50
+ }
51
+ },
52
+ });
53
+ }
54
+ //# sourceMappingURL=ssm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ssm.js","sourceRoot":"","sources":["../../src/ssm.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAkB,MAAM,qBAAqB,CAAC;AAC/F,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,gBAAgB,GAEjB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAErD,MAAM,UAAU,wBAAwB,CACtC,MAAiB,EACjB,IAAY,EACZ,OAAO,GAAkF,EAAE;IAE3F,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IACnB,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,eAAe,CAAC,2BAA2B,CAAC,CAAC;IAC7E,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC;IACnC,OAAO,WAAW,CAAC;QACjB,KAAK,CAAC,IAAI,CAAC,MAAM;YACf,MAAM,EAAE,cAAc,EAAE,CAAC;YACzB,IAAI,MAAM,CAAC;YACX,IAAI,CAAC;gBACH,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,mBAAmB,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC,EAAE;oBACxF,WAAW,EAAE,MAAM;iBACpB,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,UAAU,CAAC,KAAK,EAAE,mBAAmB,CAAC;oBAAE,MAAM,IAAI,eAAe,CAAC,WAAW,CAAC,CAAC;gBACnF,MAAM,KAAK,CAAC;YACd,CAAC;YACD,IAAI,OAAO,MAAM,CAAC,SAAS,EAAE,KAAK,KAAK,QAAQ;gBAAE,MAAM,IAAI,eAAe,CAAC,eAAe,CAAC,CAAC;YAC5F,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;YAChD,IAAI,CAAC;gBACH,OAAO,gBAAgB,CAAC,GAAG,CAAC,CAAC;YAC/B,CAAC;oBAAS,CAAC;gBACT,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACd,CAAC;QACH,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM;YACtB,MAAM,EAAE,cAAc,EAAE,CAAC;YACzB,MAAM,GAAG,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;YACpC,IAAI,CAAC;gBACH,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,UAAU,IAAI,IAAI,KAAK,qBAAqB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;oBACpF,MAAM,IAAI,eAAe,CAAC,gBAAgB,CAAC,CAAC;gBAC9C,MAAM,MAAM,CAAC,IAAI,CACf,IAAI,mBAAmB,CAAC;oBACtB,IAAI,EAAE,IAAI;oBACV,KAAK,EAAE,GAAG,CAAC,QAAQ,EAAE;oBACrB,IAAI,EAAE,cAAc;oBACpB,SAAS,EAAE,IAAI;oBACf,KAAK,EAAE,QAAQ;oBACf,IAAI,EAAE,IAAI;iBACX,CAAC,EACF,EAAE,WAAW,EAAE,MAAM,EAAE,CACxB,CAAC;YACJ,CAAC;oBAAS,CAAC;gBACT,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACd,CAAC;QACH,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { AgentStateStore } from "@layervai/qurl/node";
2
+ /** SSM and Secrets Manager have no transaction lock. One process must own each agent state. */
3
+ export declare function lockedStore(store: Omit<AgentStateStore, "withLock">): AgentStateStore;
4
+ export declare function errorNamed(error: unknown, name: string): boolean;
5
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAE3D,+FAA+F;AAC/F,wBAAgB,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,eAAe,EAAE,UAAU,CAAC,GAAG,eAAe,CAmErF;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAEhE"}
@@ -0,0 +1,82 @@
1
+ /** SSM and Secrets Manager have no transaction lock. One process must own each agent state. */
2
+ export function lockedStore(store) {
3
+ let tail = Promise.resolve();
4
+ const result = {
5
+ ...store,
6
+ save(state, signal) {
7
+ const snapshot = structuredClone(state);
8
+ return result.withLock((locked) => locked.save(snapshot, signal), signal);
9
+ },
10
+ async withLock(operation, signal) {
11
+ let release;
12
+ const previous = tail;
13
+ tail = new Promise((resolve) => {
14
+ release = resolve;
15
+ });
16
+ let entered = false;
17
+ let abort;
18
+ try {
19
+ if (signal) {
20
+ await Promise.race([
21
+ previous,
22
+ new Promise((_, reject) => {
23
+ abort = () => reject(signal.reason);
24
+ signal.addEventListener("abort", abort, { once: true });
25
+ if (signal.aborted)
26
+ abort();
27
+ }),
28
+ ]);
29
+ }
30
+ else
31
+ await previous;
32
+ entered = true;
33
+ signal?.throwIfAborted();
34
+ let active = true;
35
+ const check = () => {
36
+ if (!active)
37
+ throw new Error("qURL AWS state lock has expired");
38
+ };
39
+ const scoped = {
40
+ load: async (nextSignal) => {
41
+ check();
42
+ const effective = nextSignal ?? signal;
43
+ effective?.throwIfAborted();
44
+ const state = await store.load(effective);
45
+ check();
46
+ effective?.throwIfAborted();
47
+ return state;
48
+ },
49
+ save: async (state, nextSignal) => {
50
+ check();
51
+ const effective = nextSignal ?? signal;
52
+ effective?.throwIfAborted();
53
+ return store.save(state, effective);
54
+ },
55
+ withLock: async (operation) => {
56
+ check();
57
+ return operation(scoped);
58
+ },
59
+ };
60
+ try {
61
+ return await operation(scoped);
62
+ }
63
+ finally {
64
+ active = false;
65
+ }
66
+ }
67
+ finally {
68
+ if (abort)
69
+ signal?.removeEventListener("abort", abort);
70
+ if (entered)
71
+ release();
72
+ else
73
+ void previous.then(release);
74
+ }
75
+ },
76
+ };
77
+ return result;
78
+ }
79
+ export function errorNamed(error, name) {
80
+ return error instanceof Error && error.name === name;
81
+ }
82
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/store.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,85 @@
1
+ {
2
+ "name": "@layervai/qurl-aws",
3
+ "version": "2.0.0",
4
+ "type": "module",
5
+ "description": "AWS state adapters for qURL agent lifecycle",
6
+ "license": "MIT",
7
+ "files": [
8
+ "dist/"
9
+ ],
10
+ "exports": {
11
+ ".": {
12
+ "import": {
13
+ "types": "./dist/esm/index.d.ts",
14
+ "default": "./dist/esm/index.js"
15
+ },
16
+ "require": {
17
+ "types": "./dist/cjs/index.d.ts",
18
+ "default": "./dist/cjs/index.js"
19
+ }
20
+ },
21
+ "./ssm": {
22
+ "import": {
23
+ "types": "./dist/esm/ssm.d.ts",
24
+ "default": "./dist/esm/ssm.js"
25
+ },
26
+ "require": {
27
+ "types": "./dist/cjs/ssm.d.ts",
28
+ "default": "./dist/cjs/ssm.js"
29
+ }
30
+ },
31
+ "./secrets-manager": {
32
+ "import": {
33
+ "types": "./dist/esm/secrets-manager.d.ts",
34
+ "default": "./dist/esm/secrets-manager.js"
35
+ },
36
+ "require": {
37
+ "types": "./dist/cjs/secrets-manager.d.ts",
38
+ "default": "./dist/cjs/secrets-manager.js"
39
+ }
40
+ },
41
+ "./kms": {
42
+ "import": {
43
+ "types": "./dist/esm/kms.d.ts",
44
+ "default": "./dist/esm/kms.js"
45
+ },
46
+ "require": {
47
+ "types": "./dist/cjs/kms.d.ts",
48
+ "default": "./dist/cjs/kms.js"
49
+ }
50
+ }
51
+ },
52
+ "types": "./dist/esm/index.d.ts",
53
+ "scripts": {
54
+ "build": "node -e 'require(\"node:fs\").rmSync(\"dist\", {recursive:true, force:true})' && tsc -p tsconfig.json && tsc -p tsconfig.cjs.json && node -e 'require(\"node:fs\").writeFileSync(\"dist/cjs/package.json\", JSON.stringify({type:\"commonjs\"}))'"
55
+ },
56
+ "peerDependencies": {
57
+ "@layervai/qurl": "^2.0.0",
58
+ "@aws-sdk/client-ssm": "^3.1036.0",
59
+ "@aws-sdk/client-secrets-manager": "^3.1036.0",
60
+ "@aws-sdk/client-kms": "^3.1036.0"
61
+ },
62
+ "devDependencies": {
63
+ "@layervai/qurl": "file:../..",
64
+ "@aws-sdk/client-ssm": "3.1036.0",
65
+ "@aws-sdk/client-secrets-manager": "3.1036.0",
66
+ "@aws-sdk/client-kms": "3.1036.0"
67
+ },
68
+ "main": "./dist/cjs/index.js",
69
+ "repository": {
70
+ "type": "git",
71
+ "url": "https://github.com/layervai/qurl-typescript",
72
+ "directory": "packages/aws"
73
+ },
74
+ "peerDependenciesMeta": {
75
+ "@aws-sdk/client-ssm": {
76
+ "optional": true
77
+ },
78
+ "@aws-sdk/client-secrets-manager": {
79
+ "optional": true
80
+ },
81
+ "@aws-sdk/client-kms": {
82
+ "optional": true
83
+ }
84
+ }
85
+ }