@raisindb/functions-types 0.2.6 → 0.3.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/package.json +1 -1
- package/raisin.d.ts +141 -0
package/package.json
CHANGED
package/raisin.d.ts
CHANGED
|
@@ -393,6 +393,147 @@ declare namespace raisin {
|
|
|
393
393
|
function get(jobIdOrKey: string): Promise<any>;
|
|
394
394
|
}
|
|
395
395
|
|
|
396
|
+
/**
|
|
397
|
+
* Metadata about one secret. Never carries the secret itself — the type has
|
|
398
|
+
* no field that could hold ciphertext or plaintext.
|
|
399
|
+
*/
|
|
400
|
+
interface SecretMetadata {
|
|
401
|
+
name: string;
|
|
402
|
+
/** Human-facing ordinal, from 1. Use it as `secrets.get(name, version)`. */
|
|
403
|
+
version: number;
|
|
404
|
+
/** Which master key sealed it. */
|
|
405
|
+
key_id: number;
|
|
406
|
+
/** RFC 3339. */
|
|
407
|
+
created_at: string;
|
|
408
|
+
created_by: string;
|
|
409
|
+
/** Set only by `rotate`. */
|
|
410
|
+
rotated_at?: string | null;
|
|
411
|
+
/** The node this secret backs, when it is a vaulted schema field. */
|
|
412
|
+
owner_node?: string | null;
|
|
413
|
+
owner_field?: string | null;
|
|
414
|
+
/** True when the newest version is a tombstone. */
|
|
415
|
+
deleted: boolean;
|
|
416
|
+
ciphertext_len: number;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
/**
|
|
420
|
+
* Encrypted secret store, scoped to the current `{tenant, repo, branch}`.
|
|
421
|
+
*
|
|
422
|
+
* **Access is denied by default.** A function reaches these only if its
|
|
423
|
+
* `.node.yaml` declares a matching grant:
|
|
424
|
+
*
|
|
425
|
+
* ```yaml
|
|
426
|
+
* secret_policy:
|
|
427
|
+
* enabled: true
|
|
428
|
+
* allowed_names:
|
|
429
|
+
* - "stripe/*"
|
|
430
|
+
* - "sendgrid_api_key"
|
|
431
|
+
* ```
|
|
432
|
+
*
|
|
433
|
+
* Without one, every call below throws a `policy_denied` error naming the
|
|
434
|
+
* secret. That default is deliberate: adapters run privileged and hold
|
|
435
|
+
* `raisin.http`, so an ungated secrets binding would be a one-line
|
|
436
|
+
* exfiltration path for every credential in the repo.
|
|
437
|
+
*
|
|
438
|
+
* Every method THROWS on failure (denial, missing secret, deleted secret,
|
|
439
|
+
* unconfigured store) — none of them degrade to `null`, which would be
|
|
440
|
+
* indistinguishable from an empty credential.
|
|
441
|
+
*
|
|
442
|
+
* ## The main flow: a secret stored in a node property
|
|
443
|
+
*
|
|
444
|
+
* The common case is not a standalone secret — it is a field on a regular
|
|
445
|
+
* node declared `encrypted: true` in its NodeType. Three steps:
|
|
446
|
+
*
|
|
447
|
+
* 1. The property does not hold the credential. It holds a REFERENCE:
|
|
448
|
+
* `"secret://node/01H8XY.../api_key@1"`.
|
|
449
|
+
* 2. A node read returns that string verbatim. **Reads never resolve** —
|
|
450
|
+
* there is no query flag and no endpoint that returns a value.
|
|
451
|
+
* 3. The function passes the string straight to `get` (or `resolve`):
|
|
452
|
+
*
|
|
453
|
+
* ```javascript
|
|
454
|
+
* const node = await raisin.nodes.get('data', '/connections/stripe');
|
|
455
|
+
* const key = raisin.secrets.get(node.properties.api_key);
|
|
456
|
+
* ```
|
|
457
|
+
*
|
|
458
|
+
* Pass the reference through **as-is**. Do not strip `secret://` or the
|
|
459
|
+
* `@version` suffix yourself: a name may itself contain `@` (an operator
|
|
460
|
+
* name like `ops@example.com`), so only a trailing all-digit run after the
|
|
461
|
+
* LAST `@` is a version. `get` applies that rule using the same parser the
|
|
462
|
+
* storage layer uses.
|
|
463
|
+
*/
|
|
464
|
+
/**
|
|
465
|
+
* Declared as an interface rather than a `namespace`, because `delete` is a
|
|
466
|
+
* reserved word that TypeScript rejects as an ambient `function` name but
|
|
467
|
+
* accepts as an interface method. (The `http`, `nodes` and `admin.nodes`
|
|
468
|
+
* namespaces above still use `function delete(...)`, which does not parse —
|
|
469
|
+
* a pre-existing break, unnoticed because this package has no drift test.)
|
|
470
|
+
*/
|
|
471
|
+
interface SecretsApi {
|
|
472
|
+
/**
|
|
473
|
+
* Read a secret's plaintext.
|
|
474
|
+
*
|
|
475
|
+
* `nameOrRef` is EITHER a bare name (`"stripe_key"`) or a full reference
|
|
476
|
+
* (`"secret://node/01H8XY.../api_key@1"`) — see the three-step flow above
|
|
477
|
+
* for why the reference form is what you will usually be holding.
|
|
478
|
+
*
|
|
479
|
+
* A version pinned in the reference is HONOURED: `secret://k@1` returns
|
|
480
|
+
* version 1, not the latest. That is what makes reading an older node
|
|
481
|
+
* revision give the value that revision actually held.
|
|
482
|
+
*
|
|
483
|
+
* Passing the `version` argument **and** a pinned reference throws. Two
|
|
484
|
+
* stated versions cannot both be satisfied, and silently preferring either
|
|
485
|
+
* could return a value the node revision never held — which is the exact
|
|
486
|
+
* guarantee a pinned reference exists to provide. Pass one or the other;
|
|
487
|
+
* `get('k', 2)` and `get('secret://k', 2)` are both fine.
|
|
488
|
+
*
|
|
489
|
+
* The policy allow-list is matched against the parsed NAME, so both
|
|
490
|
+
* spellings of one secret always get the same allow/deny answer.
|
|
491
|
+
*
|
|
492
|
+
* Throws if the policy denies the name, or the secret is missing or
|
|
493
|
+
* deleted.
|
|
494
|
+
*/
|
|
495
|
+
get(nameOrRef: string, version?: number): Promise<string>;
|
|
496
|
+
/**
|
|
497
|
+
* Resolve a value that MAY be a `secret://` reference.
|
|
498
|
+
*
|
|
499
|
+
* Returns the plaintext when it is one, or the value unchanged when it is
|
|
500
|
+
* not — so a config field that is a literal password on one deployment and
|
|
501
|
+
* a vaulted reference on another is read the same way:
|
|
502
|
+
*
|
|
503
|
+
* ```javascript
|
|
504
|
+
* const password = raisin.secrets.resolve(conn.password);
|
|
505
|
+
* ```
|
|
506
|
+
*
|
|
507
|
+
* A reference that fails to resolve THROWS; it never falls back to
|
|
508
|
+
* returning the reference text, which would send `secret://...` to a
|
|
509
|
+
* provider as a credential. A plain literal is passed through without any
|
|
510
|
+
* policy check, since no secret was touched.
|
|
511
|
+
*/
|
|
512
|
+
resolve(value: string): Promise<string>;
|
|
513
|
+
/**
|
|
514
|
+
* Append a new version. Never overwrites — prior versions stay readable.
|
|
515
|
+
*
|
|
516
|
+
* Accepts a bare name or an UNPINNED reference; a pinned one
|
|
517
|
+
* (`secret://k@1`) is refused, because a write appends a new version
|
|
518
|
+
* rather than replacing that one.
|
|
519
|
+
*/
|
|
520
|
+
put(name: string, value: string): Promise<{ name: string; version: number }>;
|
|
521
|
+
/**
|
|
522
|
+
* Metadata for the newest version of every secret this function may read.
|
|
523
|
+
* Never returns values, and is filtered to the policy's allowed names.
|
|
524
|
+
*/
|
|
525
|
+
list(): Promise<SecretMetadata[]>;
|
|
526
|
+
/**
|
|
527
|
+
* Append a new version stamped as a rotation. Pinned `secret://name@N`
|
|
528
|
+
* references keep resolving to the old version.
|
|
529
|
+
*/
|
|
530
|
+
rotate(name: string, value: string): Promise<{ name: string; version: number }>;
|
|
531
|
+
/** Append a tombstone. Prior versions remain readable by pinned reference. */
|
|
532
|
+
delete(name: string): Promise<{ name: string; version: number }>;
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
const secrets: SecretsApi;
|
|
536
|
+
|
|
396
537
|
namespace sql {
|
|
397
538
|
function query(sql: string, params: any[]): Promise<any>;
|
|
398
539
|
function execute(sql: string, params: any[]): Promise<number>;
|