@inkbox/sdk 0.1.3 → 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.
Files changed (47) hide show
  1. package/README.md +42 -2
  2. package/dist/_http.d.ts +7 -1
  3. package/dist/_http.d.ts.map +1 -1
  4. package/dist/_http.js +13 -1
  5. package/dist/_http.js.map +1 -1
  6. package/dist/agent_identity.d.ts +36 -4
  7. package/dist/agent_identity.d.ts.map +1 -1
  8. package/dist/agent_identity.js +70 -6
  9. package/dist/agent_identity.js.map +1 -1
  10. package/dist/authenticator/resources/accounts.d.ts +1 -1
  11. package/dist/authenticator/resources/accounts.js +1 -1
  12. package/dist/authenticator/resources/apps.d.ts +2 -2
  13. package/dist/authenticator/resources/apps.js +2 -2
  14. package/dist/credentials.d.ts +86 -0
  15. package/dist/credentials.d.ts.map +1 -0
  16. package/dist/credentials.js +130 -0
  17. package/dist/credentials.js.map +1 -0
  18. package/dist/identities/resources/identities.d.ts +1 -1
  19. package/dist/identities/resources/identities.js +1 -1
  20. package/dist/index.d.ts +8 -1
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +6 -1
  23. package/dist/index.js.map +1 -1
  24. package/dist/inkbox.d.ts +25 -0
  25. package/dist/inkbox.d.ts.map +1 -1
  26. package/dist/inkbox.js +34 -1
  27. package/dist/inkbox.js.map +1 -1
  28. package/dist/mail/resources/messages.d.ts +2 -2
  29. package/dist/mail/resources/messages.d.ts.map +1 -1
  30. package/dist/mail/resources/messages.js.map +1 -1
  31. package/dist/mail/types.d.ts +8 -1
  32. package/dist/mail/types.d.ts.map +1 -1
  33. package/dist/mail/types.js +8 -0
  34. package/dist/mail/types.js.map +1 -1
  35. package/dist/vault/crypto.d.ts +136 -0
  36. package/dist/vault/crypto.d.ts.map +1 -0
  37. package/dist/vault/crypto.js +265 -0
  38. package/dist/vault/crypto.js.map +1 -0
  39. package/dist/vault/resources/vault.d.ts +149 -0
  40. package/dist/vault/resources/vault.d.ts.map +1 -0
  41. package/dist/vault/resources/vault.js +291 -0
  42. package/dist/vault/resources/vault.js.map +1 -0
  43. package/dist/vault/types.d.ts +236 -0
  44. package/dist/vault/types.d.ts.map +1 -0
  45. package/dist/vault/types.js +225 -0
  46. package/dist/vault/types.js.map +1 -0
  47. package/package.json +6 -2
@@ -0,0 +1,291 @@
1
+ /**
2
+ * inkbox-vault/resources/vault.ts
3
+ *
4
+ * VaultResource — org-level vault operations.
5
+ * UnlockedVault — crypto-enabled wrapper for secret CRUD after unlock.
6
+ */
7
+ import { computeAuthHash, decryptPayload, deriveMasterKey, deriveSalt, encryptPayload, unwrapOrgKey, } from "../crypto.js";
8
+ import { inferSecretType, parseAccessRule, parsePayload, parseVaultInfo, parseVaultKey, parseVaultSecret, parseVaultSecretDetail, serializePayload, } from "../types.js";
9
+ /**
10
+ * Org-level vault operations.
11
+ *
12
+ * Access via `inkbox.vault`. Most read-only operations work without
13
+ * unlocking. To create, read, or update secret payloads, call
14
+ * {@link unlock} first.
15
+ */
16
+ export class VaultResource {
17
+ /** @internal */
18
+ http;
19
+ /** @internal */
20
+ _unlocked = null;
21
+ /** @internal */
22
+ constructor(http) {
23
+ this.http = http;
24
+ }
25
+ // ------------------------------------------------------------------
26
+ // Vault metadata
27
+ // ------------------------------------------------------------------
28
+ /** Get vault metadata for the caller's organisation. */
29
+ async info() {
30
+ const data = await this.http.get("/info");
31
+ return parseVaultInfo(data);
32
+ }
33
+ // ------------------------------------------------------------------
34
+ // Keys (read-only via API key)
35
+ // ------------------------------------------------------------------
36
+ /**
37
+ * List vault keys (metadata only — no wrapped key material).
38
+ *
39
+ * @param options.keyType - Optional filter: `"primary"` or `"recovery"`.
40
+ */
41
+ async listKeys(options = {}) {
42
+ const params = {};
43
+ if (options.keyType !== undefined)
44
+ params["type"] = options.keyType;
45
+ const data = await this.http.get("/keys", params);
46
+ return data.map(parseVaultKey);
47
+ }
48
+ // ------------------------------------------------------------------
49
+ // Secrets (metadata-only operations)
50
+ // ------------------------------------------------------------------
51
+ /**
52
+ * List vault secrets (metadata only, no encrypted payload).
53
+ *
54
+ * @param options.secretType - Optional filter: `"login"`, `"ssh_key"`,
55
+ * `"api_key"`, or `"other"`.
56
+ */
57
+ async listSecrets(options = {}) {
58
+ const params = {};
59
+ if (options.secretType !== undefined)
60
+ params["secret_type"] = options.secretType;
61
+ const data = await this.http.get("/secrets", params);
62
+ return data.map(parseVaultSecret);
63
+ }
64
+ /**
65
+ * Delete a vault secret.
66
+ *
67
+ * @param secretId - UUID of the secret to delete.
68
+ */
69
+ async deleteSecret(secretId) {
70
+ await this.http.delete(`/secrets/${secretId}`);
71
+ }
72
+ // ------------------------------------------------------------------
73
+ // Access rules
74
+ // ------------------------------------------------------------------
75
+ /**
76
+ * List identity access rules for a vault secret.
77
+ *
78
+ * @param secretId - UUID of the secret.
79
+ */
80
+ async listAccessRules(secretId) {
81
+ const data = await this.http.get(`/secrets/${secretId}/access`);
82
+ return data.map(parseAccessRule);
83
+ }
84
+ /**
85
+ * Grant an identity access to a vault secret.
86
+ *
87
+ * @param secretId - UUID of the secret.
88
+ * @param identityId - UUID of the identity to grant access to.
89
+ */
90
+ async grantAccess(secretId, identityId) {
91
+ const data = await this.http.post(`/secrets/${secretId}/access`, { identity_id: identityId });
92
+ return parseAccessRule(data);
93
+ }
94
+ /**
95
+ * Revoke an identity's access to a vault secret.
96
+ *
97
+ * @param secretId - UUID of the secret.
98
+ * @param identityId - UUID of the identity to revoke access from.
99
+ */
100
+ async revokeAccess(secretId, identityId) {
101
+ await this.http.delete(`/secrets/${secretId}/access/${identityId}`);
102
+ }
103
+ // ------------------------------------------------------------------
104
+ // Unlock
105
+ // ------------------------------------------------------------------
106
+ /**
107
+ * Unlock the vault with a vault key.
108
+ *
109
+ * Derives the encryption key from the provided vault key, fetches
110
+ * and decrypts all vault secrets.
111
+ *
112
+ * @param vaultKey - Vault key or recovery code.
113
+ * @param options.identityId - Optional agent identity UUID. When
114
+ * provided, only secrets that this identity has been granted access
115
+ * to are included in {@link UnlockedVault.secrets}.
116
+ * @returns {@link UnlockedVault} with decrypted secrets and methods for
117
+ * secret CRUD.
118
+ * @throws If the vault key is incorrect or the vault key has been deleted.
119
+ */
120
+ async unlock(vaultKey, options = {}) {
121
+ // Step 1: get org_id for salt derivation
122
+ const vaultInfo = await this.info();
123
+ const salt = deriveSalt(vaultInfo.organizationId);
124
+ // Step 2: derive master key → auth hash
125
+ const masterKey = await deriveMasterKey(vaultKey, salt);
126
+ const authHash = computeAuthHash(masterKey);
127
+ // Step 3: fetch wrapped key + encrypted secrets
128
+ // We always send auth_hash, so the server returns the singular
129
+ // wrapped_org_encryption_key for the matching vault key. The
130
+ // plural wrapped_org_encryption_keys is only returned when
131
+ // auth_hash is omitted (a recovery flow this SDK does not use,
132
+ // since recovery codes are derived the same way as vault keys).
133
+ const data = await this.http.get("/unlock", {
134
+ auth_hash: authHash,
135
+ });
136
+ const wrapped = data.wrapped_org_encryption_key;
137
+ if (!wrapped) {
138
+ throw new Error("No vault key matched. " +
139
+ "Check that the vault key is correct and has not been deleted.");
140
+ }
141
+ // Step 4: unwrap the org encryption key
142
+ const orgKey = unwrapOrgKey(masterKey, wrapped);
143
+ // Step 5: decrypt all secrets from the unlock bundle
144
+ const decrypted = [];
145
+ for (const raw of data.encrypted_secrets ?? []) {
146
+ const detail = parseVaultSecretDetail(raw);
147
+ const payloadDict = decryptPayload(orgKey, detail.encryptedPayload);
148
+ const payload = parsePayload(detail.secretType, payloadDict);
149
+ decrypted.push({
150
+ id: detail.id,
151
+ name: detail.name,
152
+ description: detail.description,
153
+ secretType: detail.secretType,
154
+ status: detail.status,
155
+ createdAt: detail.createdAt,
156
+ updatedAt: detail.updatedAt,
157
+ payload,
158
+ });
159
+ }
160
+ // Always store the unfiltered vault so identity.getCredentials()
161
+ // has the full set to filter from, even when identityId is provided.
162
+ this._unlocked = new UnlockedVault(this.http, orgKey, [...decrypted]);
163
+ // Step 6 (optional): filter by identity access rules
164
+ if (options.identityId !== undefined) {
165
+ const idStr = options.identityId;
166
+ const filtered = [];
167
+ for (const secret of decrypted) {
168
+ const rules = await this.http.get(`/secrets/${secret.id}/access`);
169
+ if (rules.some((r) => r.identity_id === idStr)) {
170
+ filtered.push(secret);
171
+ }
172
+ }
173
+ return new UnlockedVault(this.http, orgKey, filtered);
174
+ }
175
+ return this._unlocked;
176
+ }
177
+ }
178
+ /**
179
+ * A vault unlocked with a valid vault key.
180
+ *
181
+ * Provides transparent encrypt/decrypt for secret CRUD operations.
182
+ *
183
+ * Obtain via {@link VaultResource.unlock}.
184
+ */
185
+ export class UnlockedVault {
186
+ http;
187
+ orgKey;
188
+ secretsCache;
189
+ constructor(http, orgKey, secretsCache) {
190
+ this.http = http;
191
+ this.orgKey = orgKey;
192
+ this.secretsCache = secretsCache;
193
+ }
194
+ /** All vault secrets decrypted from the unlock response. */
195
+ get secrets() {
196
+ return [...this.secretsCache];
197
+ }
198
+ // ------------------------------------------------------------------
199
+ // Encrypted CRUD
200
+ // ------------------------------------------------------------------
201
+ /**
202
+ * Fetch and decrypt a single vault secret.
203
+ *
204
+ * @param secretId - UUID of the secret.
205
+ */
206
+ async getSecret(secretId) {
207
+ const data = await this.http.get(`/secrets/${secretId}`);
208
+ const detail = parseVaultSecretDetail(data);
209
+ const payloadDict = decryptPayload(this.orgKey, detail.encryptedPayload);
210
+ const payload = parsePayload(detail.secretType, payloadDict);
211
+ return {
212
+ id: detail.id,
213
+ name: detail.name,
214
+ description: detail.description,
215
+ secretType: detail.secretType,
216
+ status: detail.status,
217
+ createdAt: detail.createdAt,
218
+ updatedAt: detail.updatedAt,
219
+ payload,
220
+ };
221
+ }
222
+ /**
223
+ * Encrypt and store a new secret.
224
+ *
225
+ * The `secretType` is inferred from the payload shape.
226
+ *
227
+ * @param options.name - Display name (max 255 characters).
228
+ * @param options.description - Optional description.
229
+ * @param options.payload - One of {@link LoginPayload}, {@link SSHKeyPayload},
230
+ * {@link APIKeyPayload}, or {@link OtherPayload}.
231
+ */
232
+ async createSecret(options) {
233
+ const secretType = inferSecretType(options.payload);
234
+ const serialized = serializePayload(secretType, options.payload);
235
+ const encrypted = encryptPayload(this.orgKey, serialized);
236
+ const body = {
237
+ name: options.name,
238
+ secret_type: secretType,
239
+ encrypted_payload: encrypted,
240
+ };
241
+ if (options.description !== undefined)
242
+ body["description"] = options.description;
243
+ const data = await this.http.post("/secrets", body);
244
+ return parseVaultSecret(data);
245
+ }
246
+ /**
247
+ * Update a vault secret's name, description, and/or encrypted payload.
248
+ *
249
+ * Only provided fields are sent to the server.
250
+ *
251
+ * **Note:** The `secretType` is immutable after creation. If a payload
252
+ * is provided it must be the **same type** as the original (e.g. update
253
+ * a `login` secret with a new {@link LoginPayload}). To change the
254
+ * type, delete the secret and create a new one.
255
+ *
256
+ * @param secretId - UUID of the secret to update.
257
+ * @param options.name - New display name.
258
+ * @param options.description - New description.
259
+ * @param options.payload - New payload of the **same type** as the
260
+ * original (will be re-encrypted).
261
+ */
262
+ async updateSecret(secretId, options) {
263
+ const body = {};
264
+ if ("name" in options)
265
+ body["name"] = options.name;
266
+ if ("description" in options)
267
+ body["description"] = options.description;
268
+ if (options.payload !== undefined) {
269
+ // Enforce secret_type immutability — the server treats the
270
+ // payload as opaque ciphertext and cannot check this itself.
271
+ const current = parseVaultSecret(await this.http.get(`/secrets/${secretId}`));
272
+ const newType = inferSecretType(options.payload);
273
+ if (newType !== current.secretType) {
274
+ throw new TypeError(`Cannot update a '${current.secretType}' secret with a '${newType}' payload. Delete and recreate instead.`);
275
+ }
276
+ const serialized = serializePayload(newType, options.payload);
277
+ body["encrypted_payload"] = encryptPayload(this.orgKey, serialized);
278
+ }
279
+ const data = await this.http.patch(`/secrets/${secretId}`, body);
280
+ return parseVaultSecret(data);
281
+ }
282
+ /**
283
+ * Delete a vault secret.
284
+ *
285
+ * @param secretId - UUID of the secret to delete.
286
+ */
287
+ async deleteSecret(secretId) {
288
+ await this.http.delete(`/secrets/${secretId}`);
289
+ }
290
+ }
291
+ //# sourceMappingURL=vault.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vault.js","sourceRoot":"","sources":["../../../src/vault/resources/vault.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,236 @@
1
+ /**
2
+ * inkbox-vault TypeScript SDK — public types.
3
+ *
4
+ * Includes API response types, raw JSON shapes, parsers,
5
+ * and client-side structured secret payloads.
6
+ */
7
+ /**
8
+ * Category of credential stored in a vault secret.
9
+ *
10
+ * Used as a client-side hint for which form to render. The server
11
+ * does not validate or enforce payload structure (it's opaque ciphertext).
12
+ */
13
+ export declare const VaultSecretType: {
14
+ readonly API_KEY: "api_key";
15
+ readonly KEY_PAIR: "key_pair";
16
+ readonly LOGIN: "login";
17
+ readonly SSH_KEY: "ssh_key";
18
+ readonly OTHER: "other";
19
+ };
20
+ export type VaultSecretType = (typeof VaultSecretType)[keyof typeof VaultSecretType];
21
+ /**
22
+ * Discriminator for vault key records.
23
+ *
24
+ * - `PRIMARY` — a standard vault key issued to users or agents.
25
+ * - `RECOVERY` — a recovery code generated at vault initialization.
26
+ */
27
+ export declare const VaultKeyType: {
28
+ readonly PRIMARY: "primary";
29
+ readonly RECOVERY: "recovery";
30
+ };
31
+ export type VaultKeyType = (typeof VaultKeyType)[keyof typeof VaultKeyType];
32
+ /** Vault metadata returned by the info endpoint. */
33
+ export interface VaultInfo {
34
+ id: string;
35
+ organizationId: string;
36
+ /** @example "active" */
37
+ status: string;
38
+ createdAt: Date;
39
+ updatedAt: Date;
40
+ /** Number of active primary vault keys. */
41
+ keyCount: number;
42
+ /** Number of active vault secrets. */
43
+ secretCount: number;
44
+ /** Number of active recovery keys. */
45
+ recoveryKeyCount: number;
46
+ }
47
+ /** Vault key metadata (no wrapped key material). */
48
+ export interface VaultKey {
49
+ id: string;
50
+ /** `"primary"` or `"recovery"` */
51
+ keyType: string;
52
+ /** Clerk user ID of the creator, or `null`. */
53
+ createdBy: string | null;
54
+ status: string;
55
+ createdAt: Date;
56
+ updatedAt: Date;
57
+ }
58
+ /** Vault secret metadata (no encrypted payload). */
59
+ export interface VaultSecret {
60
+ id: string;
61
+ /** Display name. */
62
+ name: string;
63
+ /** Optional description. */
64
+ description: string | null;
65
+ /** `"login"` | `"ssh_key"` | `"api_key"` | `"other"` */
66
+ secretType: string;
67
+ status: string;
68
+ createdAt: Date;
69
+ updatedAt: Date;
70
+ }
71
+ /** Vault secret including the encrypted payload. */
72
+ export interface VaultSecretDetail extends VaultSecret {
73
+ /** Base64-encoded AES-256-GCM ciphertext. */
74
+ encryptedPayload: string;
75
+ }
76
+ /** A rule granting an identity access to a vault secret. */
77
+ export interface AccessRule {
78
+ id: string;
79
+ vaultSecretId: string;
80
+ identityId: string;
81
+ createdAt: Date;
82
+ }
83
+ /** @internal */
84
+ export interface RawAccessRule {
85
+ id: string;
86
+ vault_secret_id: string;
87
+ identity_id: string;
88
+ created_at: string;
89
+ }
90
+ /** @internal */
91
+ export declare function parseAccessRule(r: RawAccessRule): AccessRule;
92
+ /** Payload for `login` secrets. At least one of `username` or `email` should be provided. */
93
+ export interface LoginPayload {
94
+ password: string;
95
+ username?: string;
96
+ email?: string;
97
+ /** URL of the service. */
98
+ url?: string;
99
+ notes?: string;
100
+ }
101
+ /** Payload for `other` (freeform catch-all) secrets. */
102
+ export interface OtherPayload {
103
+ /** Freeform content. */
104
+ data: string;
105
+ notes?: string;
106
+ }
107
+ /** Payload for `ssh_key` secrets. */
108
+ export interface SSHKeyPayload {
109
+ /** SSH private key (PEM or OpenSSH format). */
110
+ privateKey: string;
111
+ publicKey?: string;
112
+ fingerprint?: string;
113
+ /** Passphrase protecting the private key, if any. */
114
+ passphrase?: string;
115
+ notes?: string;
116
+ }
117
+ /** Payload for `api_key` secrets (single token). */
118
+ export interface APIKeyPayload {
119
+ /** The API key or token. */
120
+ apiKey: string;
121
+ /** API endpoint URL. */
122
+ endpoint?: string;
123
+ notes?: string;
124
+ }
125
+ /** Payload for `key_pair` secrets (access key + secret key). */
126
+ export interface KeyPairPayload {
127
+ /** The access key identifier. */
128
+ accessKey: string;
129
+ /** The secret key. */
130
+ secretKey: string;
131
+ /** API endpoint URL. */
132
+ endpoint?: string;
133
+ notes?: string;
134
+ }
135
+ /** Union of all secret payload types. */
136
+ export type SecretPayload = LoginPayload | OtherPayload | SSHKeyPayload | APIKeyPayload | KeyPairPayload;
137
+ /** A vault secret with its payload decrypted into a structured type. */
138
+ export interface DecryptedVaultSecret {
139
+ id: string;
140
+ /** Display name. */
141
+ name: string;
142
+ description: string | null;
143
+ /** `"login"` | `"ssh_key"` | `"api_key"` | `"other"` */
144
+ secretType: string;
145
+ status: string;
146
+ createdAt: Date;
147
+ updatedAt: Date;
148
+ /** The decrypted, structured payload. */
149
+ payload: SecretPayload;
150
+ }
151
+ /** @internal */
152
+ export interface RawVaultInfo {
153
+ id: string;
154
+ organization_id: string;
155
+ status: string;
156
+ created_at: string;
157
+ updated_at: string;
158
+ key_count: number;
159
+ secret_count: number;
160
+ recovery_key_count: number;
161
+ }
162
+ /** @internal */
163
+ export interface RawVaultKey {
164
+ id: string;
165
+ key_type: string;
166
+ created_by: string | null;
167
+ status: string;
168
+ created_at: string;
169
+ updated_at: string;
170
+ }
171
+ /** @internal */
172
+ export interface RawVaultSecret {
173
+ id: string;
174
+ name: string;
175
+ description: string | null;
176
+ secret_type: string;
177
+ status: string;
178
+ created_at: string;
179
+ updated_at: string;
180
+ }
181
+ /** @internal */
182
+ export interface RawVaultSecretDetail extends RawVaultSecret {
183
+ encrypted_payload: string;
184
+ }
185
+ /** @internal */
186
+ export interface RawVaultUnlockResponse {
187
+ wrapped_org_encryption_key: string | null;
188
+ wrapped_org_encryption_keys: Array<{
189
+ id: string;
190
+ auth_hash: string;
191
+ wrapped_org_encryption_key: string;
192
+ }> | null;
193
+ encrypted_secrets: RawVaultSecretDetail[];
194
+ }
195
+ /** Parse a raw vault info response into a {@link VaultInfo}. @internal */
196
+ export declare function parseVaultInfo(r: RawVaultInfo): VaultInfo;
197
+ /** Parse a raw vault key response into a {@link VaultKey}. @internal */
198
+ export declare function parseVaultKey(r: RawVaultKey): VaultKey;
199
+ /** Parse a raw vault secret response into a {@link VaultSecret}. @internal */
200
+ export declare function parseVaultSecret(r: RawVaultSecret): VaultSecret;
201
+ /** Parse a raw vault secret detail response into a {@link VaultSecretDetail}. @internal */
202
+ export declare function parseVaultSecretDetail(r: RawVaultSecretDetail): VaultSecretDetail;
203
+ /**
204
+ * Serialize a payload into a plain object for encryption.
205
+ *
206
+ * Converts camelCase payload fields to the snake_case wire format
207
+ * stored inside the encrypted blob.
208
+ *
209
+ * @param secretType - The secret type string.
210
+ * @param payload - The structured payload to serialize.
211
+ * @returns A plain object ready for JSON stringification.
212
+ * @throws If `secretType` is unknown.
213
+ * @internal
214
+ */
215
+ export declare function serializePayload(secretType: string, payload: SecretPayload): Record<string, unknown>;
216
+ /**
217
+ * Parse a decrypted plain object into the correct payload type.
218
+ *
219
+ * Converts snake_case wire-format fields back to camelCase.
220
+ *
221
+ * @param secretType - The secret type string.
222
+ * @param raw - The decrypted plain object.
223
+ * @returns The typed payload.
224
+ * @throws If `secretType` is unknown.
225
+ * @internal
226
+ */
227
+ export declare function parsePayload(secretType: string, raw: Record<string, unknown>): SecretPayload;
228
+ /**
229
+ * Infer the `secretType` string from a payload's shape.
230
+ *
231
+ * @param payload - A secret payload object.
232
+ * @returns The inferred secret type string.
233
+ * @throws If the payload shape doesn't match any known type.
234
+ */
235
+ export declare function inferSecretType(payload: SecretPayload): string;
236
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/vault/types.ts"],"names":[],"mappings":"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"}