@homeflare/distilled-openbao 0.2.0 → 0.2.1

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.
@@ -12,7 +12,8 @@ export declare const API_PATH = "/v1";
12
12
  /** Normalize an address (or an already-complete `/v1` root) into the API base URL. */
13
13
  export declare const normalizeBaseUrl: (addr: string) => string;
14
14
  export interface Config {
15
- readonly token: Redacted.Redacted<string>;
15
+ /** Absent for a local agent listener that supplies its own identity. */
16
+ readonly token?: Redacted.Redacted<string>;
16
17
  /** Fully-qualified API root, e.g. `http://127.0.0.1:8200/v1`. */
17
18
  readonly apiBaseUrl: string;
18
19
  /** `X-Vault-Namespace`, when the estate uses one. Absent = root namespace. */
@@ -24,7 +25,7 @@ export declare class Credentials extends Credentials_base {
24
25
  export declare const CredentialsFromEnv: Layer.Layer<Credentials, never, never>;
25
26
  /** Convenience layer from a plain token, address and optional namespace. */
26
27
  export declare const credentials: (config: {
27
- readonly token: string | Redacted.Redacted<string>;
28
+ readonly token?: string | Redacted.Redacted<string>;
28
29
  readonly addr: string;
29
30
  readonly namespace?: string;
30
31
  }) => Layer.Layer<Credentials>;
@@ -1 +1 @@
1
- {"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../src/credentials.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,KAAK,QAAQ,MAAM,iBAAiB,CAAC;AAG5C;;;;;GAKG;AACH,eAAO,MAAM,QAAQ,QAAQ,CAAC;AAc9B,sFAAsF;AACtF,eAAO,MAAM,gBAAgB,SAAU,MAAM,KAAG,MAG/C,CAAC;AAEF,MAAM,WAAW,MAAM;IACrB,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC1C,iEAAiE;IACjE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,8EAA8E;IAC9E,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;;AAED,qBAAa,WAAY,SAAQ,gBAGR;CAAG;AAQ5B,eAAO,MAAM,kBAAkB,wCAgB9B,CAAC;AAEF,4EAA4E;AAC5E,eAAO,MAAM,WAAW,WAAY;IAClC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACnD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B,KAAG,KAAK,CAAC,KAAK,CAAC,WAAW,CAWxB,CAAC"}
1
+ {"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../src/credentials.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,KAAK,QAAQ,MAAM,iBAAiB,CAAC;AAG5C;;;;;GAKG;AACH,eAAO,MAAM,QAAQ,QAAQ,CAAC;AAc9B,sFAAsF;AACtF,eAAO,MAAM,gBAAgB,SAAU,MAAM,KAAG,MAG/C,CAAC;AAEF,MAAM,WAAW,MAAM;IACrB,wEAAwE;IACxE,QAAQ,CAAC,KAAK,CAAC,EAAE,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC3C,iEAAiE;IACjE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,8EAA8E;IAC9E,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;;AAED,qBAAa,WAAY,SAAQ,gBAGR;CAAG;AAQ5B,eAAO,MAAM,kBAAkB,wCAmB9B,CAAC;AAEF,4EAA4E;AAC5E,eAAO,MAAM,WAAW,WAAY;IAClC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACpD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B,KAAG,KAAK,CAAC,KAAK,CAAC,WAAW,CAWxB,CAAC"}
@@ -44,14 +44,16 @@ export const normalizeBaseUrl = (addr) => {
44
44
  export class Credentials extends Context.Service()("OpenBaoCredentials") {
45
45
  }
46
46
  const envConfig = EffectConfig.all({
47
- token: EffectConfig.String("BAO_TOKEN"),
47
+ token: EffectConfig.String("BAO_TOKEN").pipe(EffectConfig.option),
48
48
  addr: EffectConfig.String("BAO_ADDR"),
49
49
  namespace: EffectConfig.String("BAO_NAMESPACE").pipe(EffectConfig.option),
50
50
  });
51
51
  export const CredentialsFromEnv = Layer.succeed(Credentials, envConfig.pipe(Effect.mapError(() => new ConfigError({
52
- message: "BAO_ADDR and BAO_TOKEN environment variables are required",
52
+ message: "BAO_ADDR environment variable is required",
53
53
  })), Effect.map(({ token, addr, namespace }) => ({
54
- token: Redacted.make(token),
54
+ token: token.valueOrUndefined === undefined
55
+ ? undefined
56
+ : Redacted.make(token.valueOrUndefined),
55
57
  apiBaseUrl: normalizeBaseUrl(addr),
56
58
  namespace: namespace.valueOrUndefined,
57
59
  })), Effect.orDie));
@@ -1 +1 @@
1
- {"version":3,"file":"credentials.js","sourceRoot":"","sources":["../src/credentials.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,YAAY,MAAM,eAAe,CAAC;AAC9C,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,KAAK,QAAQ,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAE3D;;;;;GAKG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,KAAK,CAAC;AAE9B;;;;;GAKG;AACH,MAAM,mBAAmB,GAAG,CAAC,IAAY,EAAU,EAAE;IACnD,IAAI,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC;IACtB,OAAO,GAAG,GAAG,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,GAAG,CAAC,CAAC,KAAK,EAAE;QAAE,GAAG,EAAE,CAAC;IACzD,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AAC5B,CAAC,CAAC;AAEF,sFAAsF;AACtF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,IAAY,EAAU,EAAE;IACvD,MAAM,OAAO,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;IAC1C,OAAO,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,GAAG,QAAQ,EAAE,CAAC;AACxE,CAAC,CAAC;AAUF,MAAM,OAAO,WAAY,SAAQ,OAAO,CAAC,OAAO,EAG7C,CAAC,oBAAoB,CAAC;CAAG;AAE5B,MAAM,SAAS,GAAG,YAAY,CAAC,GAAG,CAAC;IACjC,KAAK,EAAE,YAAY,CAAC,MAAM,CAAC,WAAW,CAAC;IACvC,IAAI,EAAE,YAAY,CAAC,MAAM,CAAC,UAAU,CAAC;IACrC,SAAS,EAAE,YAAY,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC;CAC1E,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,CAAC,OAAO,CAC7C,WAAW,EACX,SAAS,CAAC,IAAI,CACZ,MAAM,CAAC,QAAQ,CACb,GAAG,EAAE,CACH,IAAI,WAAW,CAAC;IACd,OAAO,EAAE,2DAA2D;CACrE,CAAC,CACL,EACD,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,CAAC;IAC1C,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC;IAC3B,UAAU,EAAE,gBAAgB,CAAC,IAAI,CAAC;IAClC,SAAS,EAAE,SAAS,CAAC,gBAAgB;CACtC,CAAC,CAAC,EACH,MAAM,CAAC,KAAK,CACb,CACF,CAAC;AAEF,4EAA4E;AAC5E,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,MAI3B,EAA4B,EAAE,CAC7B,KAAK,CAAC,OAAO,CACX,WAAW,EACX,MAAM,CAAC,OAAO,CAAC;IACb,KAAK,EACH,OAAO,MAAM,CAAC,KAAK,KAAK,QAAQ;QAC9B,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;QAC7B,CAAC,CAAC,MAAM,CAAC,KAAK;IAClB,UAAU,EAAE,gBAAgB,CAAC,MAAM,CAAC,IAAI,CAAC;IACzC,SAAS,EAAE,MAAM,CAAC,SAAS;CAC5B,CAAC,CACH,CAAC"}
1
+ {"version":3,"file":"credentials.js","sourceRoot":"","sources":["../src/credentials.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,YAAY,MAAM,eAAe,CAAC;AAC9C,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,KAAK,QAAQ,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAE3D;;;;;GAKG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,KAAK,CAAC;AAE9B;;;;;GAKG;AACH,MAAM,mBAAmB,GAAG,CAAC,IAAY,EAAU,EAAE;IACnD,IAAI,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC;IACtB,OAAO,GAAG,GAAG,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,GAAG,CAAC,CAAC,KAAK,EAAE;QAAE,GAAG,EAAE,CAAC;IACzD,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AAC5B,CAAC,CAAC;AAEF,sFAAsF;AACtF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,IAAY,EAAU,EAAE;IACvD,MAAM,OAAO,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;IAC1C,OAAO,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,GAAG,QAAQ,EAAE,CAAC;AACxE,CAAC,CAAC;AAWF,MAAM,OAAO,WAAY,SAAQ,OAAO,CAAC,OAAO,EAG7C,CAAC,oBAAoB,CAAC;CAAG;AAE5B,MAAM,SAAS,GAAG,YAAY,CAAC,GAAG,CAAC;IACjC,KAAK,EAAE,YAAY,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC;IACjE,IAAI,EAAE,YAAY,CAAC,MAAM,CAAC,UAAU,CAAC;IACrC,SAAS,EAAE,YAAY,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC;CAC1E,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,CAAC,OAAO,CAC7C,WAAW,EACX,SAAS,CAAC,IAAI,CACZ,MAAM,CAAC,QAAQ,CACb,GAAG,EAAE,CACH,IAAI,WAAW,CAAC;IACd,OAAO,EAAE,2CAA2C;CACrD,CAAC,CACL,EACD,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,CAAC;IAC1C,KAAK,EACH,KAAK,CAAC,gBAAgB,KAAK,SAAS;QAClC,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC;IAC3C,UAAU,EAAE,gBAAgB,CAAC,IAAI,CAAC;IAClC,SAAS,EAAE,SAAS,CAAC,gBAAgB;CACtC,CAAC,CAAC,EACH,MAAM,CAAC,KAAK,CACb,CACF,CAAC;AAEF,4EAA4E;AAC5E,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,MAI3B,EAA4B,EAAE,CAC7B,KAAK,CAAC,OAAO,CACX,WAAW,EACX,MAAM,CAAC,OAAO,CAAC;IACb,KAAK,EACH,OAAO,MAAM,CAAC,KAAK,KAAK,QAAQ;QAC9B,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;QAC7B,CAAC,CAAC,MAAM,CAAC,KAAK;IAClB,UAAU,EAAE,gBAAgB,CAAC,MAAM,CAAC,IAAI,CAAC;IACzC,SAAS,EAAE,MAAM,CAAC,SAAS;CAC5B,CAAC,CACH,CAAC"}
package/dist/errors.d.ts CHANGED
@@ -16,7 +16,7 @@
16
16
  * status (and message, when OpenBao supplies one) under `patches/`.
17
17
  */
18
18
  export { BadGateway, BadRequest, Conflict, ConfigError, Forbidden, GatewayTimeout, InternalServerError, Locked, NotFound, ServiceUnavailable, TooManyRequests, Unauthorized, UnprocessableEntity, HTTP_STATUS_MAP, DEFAULT_ERRORS, API_ERRORS, } from "@distilled.cloud/core/errors";
19
- import type { DefaultErrors as CoreDefaultErrors } from "@distilled.cloud/core/errors";
19
+ import type { API_ERRORS } from "@distilled.cloud/core/errors";
20
20
  import * as Schema from "effect/Schema";
21
21
  declare const UnknownOpenBaoError_base: Schema.Class<UnknownOpenBaoError, Schema.TaggedStruct<"UnknownOpenBaoError", {
22
22
  readonly code: Schema.optional<Schema.String>;
@@ -53,5 +53,5 @@ export type ClientErrors = UnknownOpenBaoError | OpenBaoParseError;
53
53
  * Default OpenBao operation errors: the shared HTTP status errors from core
54
54
  * plus the client-level fallback/decode errors.
55
55
  */
56
- export type DefaultErrors = CoreDefaultErrors | ClientErrors;
56
+ export type DefaultErrors = InstanceType<(typeof API_ERRORS)[number]> | ClientErrors;
57
57
  //# sourceMappingURL=errors.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EACL,UAAU,EACV,UAAU,EACV,QAAQ,EACR,WAAW,EACX,SAAS,EACT,cAAc,EACd,mBAAmB,EACnB,MAAM,EACN,QAAQ,EACR,kBAAkB,EAClB,eAAe,EACf,YAAY,EACZ,mBAAmB,EACnB,eAAe,EACf,cAAc,EACd,UAAU,GACX,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,aAAa,IAAI,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAEvF,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;;;;;;;;;;AAGxC;;;GAGG;AACH,qBAAa,mBAAoB,SAAQ,wBAOT;CAAG;;;;;;;;;AAEnC,kCAAkC;AAClC,qBAAa,iBAAkB,SAAQ,sBAMR;CAAG;AAElC;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,mBAAmB,GAAG,iBAAiB,CAAC;AAEnE;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG,iBAAiB,GAAG,YAAY,CAAC"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EACL,UAAU,EACV,UAAU,EACV,QAAQ,EACR,WAAW,EACX,SAAS,EACT,cAAc,EACd,mBAAmB,EACnB,MAAM,EACN,QAAQ,EACR,kBAAkB,EAClB,eAAe,EACf,YAAY,EACZ,mBAAmB,EACnB,eAAe,EACf,cAAc,EACd,UAAU,GACX,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAE/D,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;;;;;;;;;;AAGxC;;;GAGG;AACH,qBAAa,mBAAoB,SAAQ,wBAOT;CAAG;;;;;;;;;AAEnC,kCAAkC;AAClC,qBAAa,iBAAkB,SAAQ,sBAMR;CAAG;AAElC;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,mBAAmB,GAAG,iBAAiB,CAAC;AAEnE;;;GAGG;AACH,MAAM,MAAM,aAAa,GACrB,YAAY,CAAC,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC,GACzC,YAAY,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=protocol-requests.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol-requests.test.d.ts","sourceRoot":"","sources":["../src/protocol-requests.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,32 @@
1
+ import { expect, test } from "bun:test";
2
+ import * as Effect from "effect/Effect";
3
+ import * as Layer from "effect/Layer";
4
+ import * as HttpClient from "effect/unstable/http/HttpClient";
5
+ import * as HttpClientResponse from "effect/unstable/http/HttpClientResponse";
6
+ import { credentials } from "./credentials.js";
7
+ import * as Retry from "./retry.js";
8
+ import { policiesDeleteAclPolicy } from "./services/policies.js";
9
+ for (const token of [undefined, "", "test-token"]) {
10
+ test(`agent request header is present; ${token ? "nonempty" : "absent or empty"} token has correct header semantics`, async () => {
11
+ const client = HttpClient.make((request) => {
12
+ expect(request.headers["x-vault-request"]).toBe("true");
13
+ if (token)
14
+ expect(request.headers["x-vault-token"]).toBe(token);
15
+ else
16
+ expect(request.headers["x-vault-token"]).toBeUndefined();
17
+ expect(request.headers["x-vault-namespace"]).toBeUndefined();
18
+ return Effect.succeed(HttpClientResponse.fromWeb(request, new Response(null, { status: 204 })));
19
+ });
20
+ await Effect.runPromise(policiesDeleteAclPolicy({ name: "test" }).pipe(Retry.none, Effect.provide(Layer.mergeAll(Layer.succeed(HttpClient.HttpClient, client), credentials({ addr: "http://fake.invalid", token })))));
21
+ });
22
+ }
23
+ test("every status mapped by the protocol is represented in the operation error union", async () => {
24
+ // These catchTag calls must compile: core DEFAULT_ERRORS excludes both tags,
25
+ // but OpenBaoProtocol's default HTTP_STATUS_MAP emits them for every operation.
26
+ for (const status of [403, 404]) {
27
+ const client = HttpClient.make((request) => Effect.succeed(HttpClientResponse.fromWeb(request, Response.json({ errors: [] }, { status }))));
28
+ const tag = await Effect.runPromise(policiesDeleteAclPolicy({ name: "test" }).pipe(Retry.none, Effect.as("success"), Effect.catchTag("Forbidden", () => Effect.succeed("Forbidden")), Effect.catchTag("NotFound", () => Effect.succeed("NotFound")), Effect.provide(Layer.mergeAll(Layer.succeed(HttpClient.HttpClient, client), credentials({ addr: "http://fake.invalid", token: "test-token" })))));
29
+ expect(tag).toBe(status === 403 ? "Forbidden" : "NotFound");
30
+ }
31
+ });
32
+ //# sourceMappingURL=protocol-requests.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol-requests.test.js","sourceRoot":"","sources":["../src/protocol-requests.test.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAyCA,OAAO,KAAK,KAAK,KAAK,MAAM,cAAc,CAAC;AAE3C,OAAO,KAAK,KAAK,UAAU,MAAM,iCAAiC,CAAC;AACnE,OAAO,KAAK,KAAK,eAAe,MAAM,sCAAsC,CAAC;AAC7E,OAAO,KAAK,KAAK,GAAG,MAAM,2BAA2B,CAAC;AACtD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAKhE,OAAO,EAAE,WAAW,EAAe,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAuB,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAEtE;;;;;GAKG;AACH,MAAM,MAAM,cAAc,GACtB,aAAa,GACb,WAAW,GACX,eAAe,CAAC,eAAe,CAAC;AAEpC,0EAA0E;AAC1E,MAAM,MAAM,gBAAgB,GAAG,WAAW,GAAG,UAAU,CAAC,UAAU,CAAC;AAyBnE,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CA4BlD,CAAC"}
1
+ {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AA2CA,OAAO,KAAK,KAAK,KAAK,MAAM,cAAc,CAAC;AAE3C,OAAO,KAAK,KAAK,UAAU,MAAM,iCAAiC,CAAC;AACnE,OAAO,KAAK,KAAK,eAAe,MAAM,sCAAsC,CAAC;AAC7E,OAAO,KAAK,KAAK,GAAG,MAAM,2BAA2B,CAAC;AACtD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAKhE,OAAO,EAAE,WAAW,EAAe,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAuB,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAEtE;;;;;GAKG;AACH,MAAM,MAAM,cAAc,GACtB,aAAa,GACb,WAAW,GACX,eAAe,CAAC,eAAe,CAAC;AAEpC,0EAA0E;AAC1E,MAAM,MAAM,gBAAgB,GAAG,WAAW,GAAG,UAAU,CAAC,UAAU,CAAC;AAyBnE,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CA+BlD,CAAC"}
package/dist/protocol.js CHANGED
@@ -31,9 +31,11 @@
31
31
  * match on status, or on message when OpenBao actually supplies one — see
32
32
  * `patches/`.
33
33
  *
34
- * Authentication is a single header, `X-Vault-Token`, plus an optional
35
- * `X-Vault-Namespace` when the credential carries one — the estate always
36
- * does (`BAO_NAMESPACE=homeflare`). A namespace does not change a mounted
34
+ * Authentication is `X-Vault-Token` when a credential carries a nonempty
35
+ * token; omit it for a local agent that supplies its own identity. An
36
+ * optional `X-Vault-Namespace` selects a namespace; absent means root.
37
+ * `X-Vault-Request: true` admits agent listeners with require_request_header
38
+ * (OpenBao v2.6.2 command/agent.go:544-548). A namespace does not change a mounted
37
39
  * backend's own path shape (see `stacks/distilled-submodules/spec-repos/
38
40
  * openbao/fetch-specs.ts`'s module docs for how that was confirmed), so it
39
41
  * is purely a request header here, never a path segment.
@@ -77,7 +79,10 @@ export const OpenBaoProtocol = makeRestProtocol({
77
79
  }),
78
80
  baseUrl: (creds) => creds.apiBaseUrl,
79
81
  headers: (creds) => ({
80
- "X-Vault-Token": Redacted.value(creds.token),
82
+ ...(creds.token && Redacted.value(creds.token) !== ""
83
+ ? { "X-Vault-Token": Redacted.value(creds.token) }
84
+ : {}),
85
+ "X-Vault-Request": "true",
81
86
  ...(creds.namespace ? { "X-Vault-Namespace": creds.namespace } : {}),
82
87
  Accept: "application/json",
83
88
  }),
@@ -1 +1 @@
1
- {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAExC,OAAO,KAAK,QAAQ,MAAM,iBAAiB,CAAC;AAK5C,OAAO,EACL,gBAAgB,GAEjB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAe,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAsB,MAAM,aAAa,CAAC;AAgBtE;;;;;;;GAOG;AACH,MAAM,aAAa,GAAG,CAAC,IAAa,EAAiC,EAAE;IACrE,IAAI,IAAI,KAAK,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IAChE,MAAM,CAAC,GAAG,IAA+B,CAAC;IAC1C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;QAAE,OAAO,SAAS,CAAC;IAC/C,MAAM,QAAQ,GAAG,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC;IAC5E,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC;AAC5E,CAAC,CAAC;AAEF,gEAAgE;AAChE,MAAM,iBAAiB,GAAG,CAAC,IAAa,EAAW,EAAE;IACnD,IAAI,IAAI,KAAK,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC3D,MAAM,IAAI,GAAI,IAAgC,CAAC,IAAI,CAAC;IACpD,OAAO,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AACjE,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAC1B,gBAAgB,CAAS;IACvB,uEAAuE;IACvE,wEAAwE;IACxE,2DAA2D;IAC3D,WAAW,EAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QAC/B,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,WAAW,CAAC;QACnC,OAAO,KAAK,CAAC,CAAC,OAAO,CAAC;IACxB,CAAC,CAAC;IACF,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,UAAU;IACpC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACnB,eAAe,EAAE,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC;QAC5C,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,mBAAmB,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACpE,MAAM,EAAE,kBAAkB;KAC3B,CAAC;IACF,aAAa;IACb,iBAAiB;IACjB,YAAY,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,CACxC,IAAI,mBAAmB,CAAC;QACtB,IAAI,EACF,OAAO,IAAI,KAAK,QAAQ;YACtB,CAAC,CAAC,IAAI;YACN,CAAC,CAAC,IAAI,KAAK,SAAS;gBAClB,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC;gBACd,CAAC,CAAC,SAAS;QACjB,OAAO;QACP,IAAI;KACL,CAAC;CACL,CAAC,CAAC"}
1
+ {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"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"}
package/dist/retry.d.ts CHANGED
@@ -10,11 +10,10 @@
10
10
  * `packages/alchemy/src/openbao/bao-http.ts` caps in-flight OpenBao
11
11
  * exchanges at 8 process-wide (`BaoGate`, a `Semaphore`) after a real
12
12
  * outage: unbounded Alchemy fan-out took the dev listener's socket down
13
- * (measured 2026-09-14). That cap is `HttpClient` middleware, not a retry
14
- * policy, and stays exactly where it is — the kit's Effect runtime provides
15
- * the gated `HttpClient.HttpClient` layer underneath whichever protocol
16
- * (hand-rolled or this SDK) issues the request, so it keeps applying
17
- * unchanged to every call this package makes.
13
+ * (measured 2026-09-14). That cap lives inside the kit's call runner, not
14
+ * inside HttpClient. SDK consumers must explicitly share the same gate;
15
+ * merely supplying the HTTP client does not apply it. The kit runner also
16
+ * selects Retry.none so a failed response cannot repeat a sent write.
18
17
  *
19
18
  * @example
20
19
  * ```ts
@@ -1 +1 @@
1
- {"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../src/retry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAExC,OAAO,KAAK,OAAO,MAAM,6BAA6B,CAAC;AAEvD,MAAM,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;AACtC,MAAM,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;AACtC,MAAM,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;;AAEpC,uEAAuE;AACvE,qBAAa,KAAM,SAAQ,UAAgD;CAAG;AAE9E,yEAAyE;AACzE,eAAO,MAAM,MAAM,EAAE;IACnB,CACE,OAAO,EAAE,OAAO,GACf,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EACT,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAC3B,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;IAC5C,CACE,OAAO,EAAE,OAAO,GACf,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EACT,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAC3B,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;CAEU,CAAC;AAEzD,sCAAsC;AACtC,eAAO,MAAM,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EACzB,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAC3B,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,EAAE,KAAK,CAAC,CAEzC,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,WAAW,EAAE,OAA6B,CAAC;AAExD,eAAO,MAAM,QAAQ,0JAAmB,CAAC;AACzC,eAAO,MAAM,MAAM,uMAAiB,CAAC;AAErC,mEAAmE;AACnE,eAAO,MAAM,iBAAiB,EAAE,OAAmC,CAAC;AAEpE,0EAA0E;AAC1E,eAAO,MAAM,UAAU,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAC/B,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAC3B,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,EAAE,KAAK,CAAC,CAAqC,CAAC;AAEhF,kEAAkE;AAClE,eAAO,MAAM,gBAAgB,EAAE,OAAkC,CAAC;AAElE,yEAAyE;AACzE,eAAO,MAAM,SAAS,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAC9B,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAC3B,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,EAAE,KAAK,CAAC,CAAoC,CAAC"}
1
+ {"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../src/retry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAExC,OAAO,KAAK,OAAO,MAAM,6BAA6B,CAAC;AAEvD,MAAM,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;AACtC,MAAM,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;AACtC,MAAM,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;;AAEpC,uEAAuE;AACvE,qBAAa,KAAM,SAAQ,UAAgD;CAAG;AAE9E,yEAAyE;AACzE,eAAO,MAAM,MAAM,EAAE;IACnB,CACE,OAAO,EAAE,OAAO,GACf,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EACT,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAC3B,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;IAC5C,CACE,OAAO,EAAE,OAAO,GACf,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EACT,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAC3B,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;CAEU,CAAC;AAEzD,sCAAsC;AACtC,eAAO,MAAM,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EACzB,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAC3B,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,EAAE,KAAK,CAAC,CAEzC,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,WAAW,EAAE,OAA6B,CAAC;AAExD,eAAO,MAAM,QAAQ,0JAAmB,CAAC;AACzC,eAAO,MAAM,MAAM,uMAAiB,CAAC;AAErC,mEAAmE;AACnE,eAAO,MAAM,iBAAiB,EAAE,OAAmC,CAAC;AAEpE,0EAA0E;AAC1E,eAAO,MAAM,UAAU,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAC/B,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAC3B,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,EAAE,KAAK,CAAC,CAAqC,CAAC;AAEhF,kEAAkE;AAClE,eAAO,MAAM,gBAAgB,EAAE,OAAkC,CAAC;AAElE,yEAAyE;AACzE,eAAO,MAAM,SAAS,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAC9B,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAC3B,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,EAAE,KAAK,CAAC,CAAoC,CAAC"}
package/dist/retry.js CHANGED
@@ -10,11 +10,10 @@
10
10
  * `packages/alchemy/src/openbao/bao-http.ts` caps in-flight OpenBao
11
11
  * exchanges at 8 process-wide (`BaoGate`, a `Semaphore`) after a real
12
12
  * outage: unbounded Alchemy fan-out took the dev listener's socket down
13
- * (measured 2026-09-14). That cap is `HttpClient` middleware, not a retry
14
- * policy, and stays exactly where it is — the kit's Effect runtime provides
15
- * the gated `HttpClient.HttpClient` layer underneath whichever protocol
16
- * (hand-rolled or this SDK) issues the request, so it keeps applying
17
- * unchanged to every call this package makes.
13
+ * (measured 2026-09-14). That cap lives inside the kit's call runner, not
14
+ * inside HttpClient. SDK consumers must explicitly share the same gate;
15
+ * merely supplying the HTTP client does not apply it. The kit runner also
16
+ * selects Retry.none so a failed response cannot repeat a sent write.
18
17
  *
19
18
  * @example
20
19
  * ```ts
package/dist/retry.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"retry.js","sourceRoot":"","sources":["../src/retry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,KAAK,OAAO,MAAM,6BAA6B,CAAC;AAMvD,uEAAuE;AACvE,MAAM,OAAO,KAAM,SAAQ,OAAO,CAAC,OAAO,EAAiB,CAAC,cAAc,CAAC;CAAG;AAE9E,yEAAyE;AACzE,MAAM,CAAC,MAAM,MAAM,GAWf,CAAC,gBAAmC,EAAE,EAAE,CAC1C,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,gBAAgB,CAAC,CAAC,CAAC;AAEzD,sCAAsC;AACtC,MAAM,CAAC,MAAM,IAAI,GAE6B,MAAM,CAAC,OAAO,CAC1D,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,KAAK,EAAE,CAAC,CAC7C,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,WAAW,GAAY,OAAO,CAAC,WAAW,CAAC;AAExD,MAAM,CAAC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;AACzC,MAAM,CAAC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;AAErC,mEAAmE;AACnE,MAAM,CAAC,MAAM,iBAAiB,GAAY,OAAO,CAAC,iBAAiB,CAAC;AAEpE,0EAA0E;AAC1E,MAAM,CAAC,MAAM,UAAU,GAEuB,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAEhF,kEAAkE;AAClE,MAAM,CAAC,MAAM,gBAAgB,GAAY,OAAO,CAAC,gBAAgB,CAAC;AAElE,yEAAyE;AACzE,MAAM,CAAC,MAAM,SAAS,GAEwB,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC"}
1
+ {"version":3,"file":"retry.js","sourceRoot":"","sources":["../src/retry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,KAAK,OAAO,MAAM,6BAA6B,CAAC;AAMvD,uEAAuE;AACvE,MAAM,OAAO,KAAM,SAAQ,OAAO,CAAC,OAAO,EAAiB,CAAC,cAAc,CAAC;CAAG;AAE9E,yEAAyE;AACzE,MAAM,CAAC,MAAM,MAAM,GAWf,CAAC,gBAAmC,EAAE,EAAE,CAC1C,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,gBAAgB,CAAC,CAAC,CAAC;AAEzD,sCAAsC;AACtC,MAAM,CAAC,MAAM,IAAI,GAE6B,MAAM,CAAC,OAAO,CAC1D,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,KAAK,EAAE,CAAC,CAC7C,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,WAAW,GAAY,OAAO,CAAC,WAAW,CAAC;AAExD,MAAM,CAAC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;AACzC,MAAM,CAAC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;AAErC,mEAAmE;AACnE,MAAM,CAAC,MAAM,iBAAiB,GAAY,OAAO,CAAC,iBAAiB,CAAC;AAEpE,0EAA0E;AAC1E,MAAM,CAAC,MAAM,UAAU,GAEuB,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAEhF,kEAAkE;AAClE,MAAM,CAAC,MAAM,gBAAgB,GAAY,OAAO,CAAC,gBAAgB,CAAC;AAElE,yEAAyE;AACzE,MAAM,CAAC,MAAM,SAAS,GAEwB,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@homeflare/distilled-openbao",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "Interim npm home for @distilled.cloud/openbao — see docs/distilled-interim.md. Not published upstream yet; the kit aliases @distilled.cloud/openbao onto this package until it is.",
5
5
  "homepage": "https://github.com/taslabs-net/homeflare-kit/tree/main/packages/distilled-openbao#readme",
6
6
  "bugs": "https://github.com/taslabs-net/homeflare-kit/issues",
@@ -45,7 +45,8 @@ export const normalizeBaseUrl = (addr: string): string => {
45
45
  };
46
46
 
47
47
  export interface Config {
48
- readonly token: Redacted.Redacted<string>;
48
+ /** Absent for a local agent listener that supplies its own identity. */
49
+ readonly token?: Redacted.Redacted<string>;
49
50
  /** Fully-qualified API root, e.g. `http://127.0.0.1:8200/v1`. */
50
51
  readonly apiBaseUrl: string;
51
52
  /** `X-Vault-Namespace`, when the estate uses one. Absent = root namespace. */
@@ -58,7 +59,7 @@ export class Credentials extends Context.Service<
58
59
  >()("OpenBaoCredentials") {}
59
60
 
60
61
  const envConfig = EffectConfig.all({
61
- token: EffectConfig.String("BAO_TOKEN"),
62
+ token: EffectConfig.String("BAO_TOKEN").pipe(EffectConfig.option),
62
63
  addr: EffectConfig.String("BAO_ADDR"),
63
64
  namespace: EffectConfig.String("BAO_NAMESPACE").pipe(EffectConfig.option),
64
65
  });
@@ -69,11 +70,14 @@ export const CredentialsFromEnv = Layer.succeed(
69
70
  Effect.mapError(
70
71
  () =>
71
72
  new ConfigError({
72
- message: "BAO_ADDR and BAO_TOKEN environment variables are required",
73
+ message: "BAO_ADDR environment variable is required",
73
74
  }),
74
75
  ),
75
76
  Effect.map(({ token, addr, namespace }) => ({
76
- token: Redacted.make(token),
77
+ token:
78
+ token.valueOrUndefined === undefined
79
+ ? undefined
80
+ : Redacted.make(token.valueOrUndefined),
77
81
  apiBaseUrl: normalizeBaseUrl(addr),
78
82
  namespace: namespace.valueOrUndefined,
79
83
  })),
@@ -83,7 +87,7 @@ export const CredentialsFromEnv = Layer.succeed(
83
87
 
84
88
  /** Convenience layer from a plain token, address and optional namespace. */
85
89
  export const credentials = (config: {
86
- readonly token: string | Redacted.Redacted<string>;
90
+ readonly token?: string | Redacted.Redacted<string>;
87
91
  readonly addr: string;
88
92
  readonly namespace?: string;
89
93
  }): Layer.Layer<Credentials> =>
package/src/errors.ts CHANGED
@@ -33,7 +33,7 @@ export {
33
33
  DEFAULT_ERRORS,
34
34
  API_ERRORS,
35
35
  } from "@distilled.cloud/core/errors";
36
- import type { DefaultErrors as CoreDefaultErrors } from "@distilled.cloud/core/errors";
36
+ import type { API_ERRORS } from "@distilled.cloud/core/errors";
37
37
 
38
38
  import * as Schema from "effect/Schema";
39
39
  import * as Category from "@distilled.cloud/core/category";
@@ -70,4 +70,6 @@ export type ClientErrors = UnknownOpenBaoError | OpenBaoParseError;
70
70
  * Default OpenBao operation errors: the shared HTTP status errors from core
71
71
  * plus the client-level fallback/decode errors.
72
72
  */
73
- export type DefaultErrors = CoreDefaultErrors | ClientErrors;
73
+ export type DefaultErrors =
74
+ | InstanceType<(typeof API_ERRORS)[number]>
75
+ | ClientErrors;
@@ -0,0 +1,66 @@
1
+ import { expect, test } from "bun:test";
2
+ import * as Effect from "effect/Effect";
3
+ import * as Layer from "effect/Layer";
4
+ import * as HttpClient from "effect/unstable/http/HttpClient";
5
+ import * as HttpClientResponse from "effect/unstable/http/HttpClientResponse";
6
+ import { credentials } from "./credentials.ts";
7
+ import * as Retry from "./retry.ts";
8
+ import { policiesDeleteAclPolicy } from "./services/policies.ts";
9
+
10
+ for (const token of [undefined, "", "test-token"]) {
11
+ test(`agent request header is present; ${token ? "nonempty" : "absent or empty"} token has correct header semantics`, async () => {
12
+ const client = HttpClient.make((request) => {
13
+ expect(request.headers["x-vault-request"]).toBe("true");
14
+ if (token) expect(request.headers["x-vault-token"]).toBe(token);
15
+ else expect(request.headers["x-vault-token"]).toBeUndefined();
16
+ expect(request.headers["x-vault-namespace"]).toBeUndefined();
17
+ return Effect.succeed(
18
+ HttpClientResponse.fromWeb(
19
+ request,
20
+ new Response(null, { status: 204 }),
21
+ ),
22
+ );
23
+ });
24
+ await Effect.runPromise(
25
+ policiesDeleteAclPolicy({ name: "test" }).pipe(
26
+ Retry.none,
27
+ Effect.provide(
28
+ Layer.mergeAll(
29
+ Layer.succeed(HttpClient.HttpClient, client),
30
+ credentials({ addr: "http://fake.invalid", token }),
31
+ ),
32
+ ),
33
+ ),
34
+ );
35
+ });
36
+ }
37
+
38
+ test("every status mapped by the protocol is represented in the operation error union", async () => {
39
+ // These catchTag calls must compile: core DEFAULT_ERRORS excludes both tags,
40
+ // but OpenBaoProtocol's default HTTP_STATUS_MAP emits them for every operation.
41
+ for (const status of [403, 404]) {
42
+ const client = HttpClient.make((request) =>
43
+ Effect.succeed(
44
+ HttpClientResponse.fromWeb(
45
+ request,
46
+ Response.json({ errors: [] }, { status }),
47
+ ),
48
+ ),
49
+ );
50
+ const tag = await Effect.runPromise(
51
+ policiesDeleteAclPolicy({ name: "test" }).pipe(
52
+ Retry.none,
53
+ Effect.as("success"),
54
+ Effect.catchTag("Forbidden", () => Effect.succeed("Forbidden")),
55
+ Effect.catchTag("NotFound", () => Effect.succeed("NotFound")),
56
+ Effect.provide(
57
+ Layer.mergeAll(
58
+ Layer.succeed(HttpClient.HttpClient, client),
59
+ credentials({ addr: "http://fake.invalid", token: "test-token" }),
60
+ ),
61
+ ),
62
+ ),
63
+ );
64
+ expect(tag).toBe(status === 403 ? "Forbidden" : "NotFound");
65
+ }
66
+ });
package/src/protocol.ts CHANGED
@@ -31,9 +31,11 @@
31
31
  * match on status, or on message when OpenBao actually supplies one — see
32
32
  * `patches/`.
33
33
  *
34
- * Authentication is a single header, `X-Vault-Token`, plus an optional
35
- * `X-Vault-Namespace` when the credential carries one — the estate always
36
- * does (`BAO_NAMESPACE=homeflare`). A namespace does not change a mounted
34
+ * Authentication is `X-Vault-Token` when a credential carries a nonempty
35
+ * token; omit it for a local agent that supplies its own identity. An
36
+ * optional `X-Vault-Namespace` selects a namespace; absent means root.
37
+ * `X-Vault-Request: true` admits agent listeners with require_request_header
38
+ * (OpenBao v2.6.2 command/agent.go:544-548). A namespace does not change a mounted
37
39
  * backend's own path shape (see `stacks/distilled-submodules/spec-repos/
38
40
  * openbao/fetch-specs.ts`'s module docs for how that was confirmed), so it
39
41
  * is purely a request header here, never a path segment.
@@ -100,7 +102,10 @@ export const OpenBaoProtocol: Layer.Layer<API.Protocol> =
100
102
  }),
101
103
  baseUrl: (creds) => creds.apiBaseUrl,
102
104
  headers: (creds) => ({
103
- "X-Vault-Token": Redacted.value(creds.token),
105
+ ...(creds.token && Redacted.value(creds.token) !== ""
106
+ ? { "X-Vault-Token": Redacted.value(creds.token) }
107
+ : {}),
108
+ "X-Vault-Request": "true",
104
109
  ...(creds.namespace ? { "X-Vault-Namespace": creds.namespace } : {}),
105
110
  Accept: "application/json",
106
111
  }),
package/src/retry.ts CHANGED
@@ -10,11 +10,10 @@
10
10
  * `packages/alchemy/src/openbao/bao-http.ts` caps in-flight OpenBao
11
11
  * exchanges at 8 process-wide (`BaoGate`, a `Semaphore`) after a real
12
12
  * outage: unbounded Alchemy fan-out took the dev listener's socket down
13
- * (measured 2026-09-14). That cap is `HttpClient` middleware, not a retry
14
- * policy, and stays exactly where it is — the kit's Effect runtime provides
15
- * the gated `HttpClient.HttpClient` layer underneath whichever protocol
16
- * (hand-rolled or this SDK) issues the request, so it keeps applying
17
- * unchanged to every call this package makes.
13
+ * (measured 2026-09-14). That cap lives inside the kit's call runner, not
14
+ * inside HttpClient. SDK consumers must explicitly share the same gate;
15
+ * merely supplying the HTTP client does not apply it. The kit runner also
16
+ * selects Retry.none so a failed response cannot repeat a sent write.
18
17
  *
19
18
  * @example
20
19
  * ```ts