@aventara/access 0.0.0-stage → 0.1.0-rc.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 (240) hide show
  1. package/CHANGELOG.md +831 -0
  2. package/LICENSE +91 -0
  3. package/LICENSE-ADDITIONAL-PERMISSION.md +9 -0
  4. package/README.md +2439 -2
  5. package/dist/access/access-options.d.ts +66 -0
  6. package/dist/access/access-options.js +5 -0
  7. package/dist/access/access.error.d.ts +35 -0
  8. package/dist/access/access.error.js +11 -0
  9. package/dist/access/access.factory.d.ts +273 -0
  10. package/dist/access/access.factory.js +440 -0
  11. package/dist/access/better-auth.hardening.d.ts +120 -0
  12. package/dist/access/better-auth.hardening.js +420 -0
  13. package/dist/access/better-auth.loader.d.ts +67 -0
  14. package/dist/access/better-auth.loader.js +65 -0
  15. package/dist/access/better-auth.range.d.ts +9 -0
  16. package/dist/access/better-auth.range.js +28 -0
  17. package/dist/access/better-auth.require.d.ts +90 -0
  18. package/dist/access/better-auth.require.js +6 -0
  19. package/dist/access/better-auth.require.node.d.ts +7 -0
  20. package/dist/access/better-auth.require.node.js +52 -0
  21. package/dist/access/claims.mapper.d.ts +79 -0
  22. package/dist/access/claims.mapper.js +152 -0
  23. package/dist/access/key-set.cache.d.ts +10 -0
  24. package/dist/access/key-set.cache.js +63 -0
  25. package/dist/access/policies-block.checker.d.ts +64 -0
  26. package/dist/access/policies-block.checker.js +138 -0
  27. package/dist/access/principal.subject.d.ts +12 -0
  28. package/dist/access/principal.subject.js +60 -0
  29. package/dist/access/profile.policy.d.ts +74 -0
  30. package/dist/access/profile.policy.js +110 -0
  31. package/dist/access/request.state.d.ts +89 -0
  32. package/dist/access/request.state.js +196 -0
  33. package/dist/access/session.hooks.d.ts +114 -0
  34. package/dist/access/session.hooks.js +258 -0
  35. package/dist/access/token.verifier.d.ts +35 -0
  36. package/dist/access/token.verifier.js +69 -0
  37. package/dist/access-schema.d.ts +48 -0
  38. package/dist/access-schema.js +5 -0
  39. package/dist/access-warning.emitter.d.ts +2 -0
  40. package/dist/access-warning.emitter.js +20 -0
  41. package/dist/access.builder.d.ts +299 -0
  42. package/dist/access.builder.js +66 -0
  43. package/dist/access.engine.d.ts +142 -0
  44. package/dist/access.engine.js +470 -0
  45. package/dist/audit/audit-event.d.ts +135 -0
  46. package/dist/audit/audit-event.js +8 -0
  47. package/dist/audit/audit.log.d.ts +122 -0
  48. package/dist/audit/audit.log.js +345 -0
  49. package/dist/audit/audit.schema.d.ts +143 -0
  50. package/dist/audit/audit.schema.js +50 -0
  51. package/dist/auth/index.d.ts +12 -0
  52. package/dist/auth/index.js +2 -0
  53. package/dist/aventara-where.translator.d.ts +19 -0
  54. package/dist/aventara-where.translator.js +87 -0
  55. package/dist/beacon/beacon.check.d.ts +59 -0
  56. package/dist/beacon/beacon.check.js +128 -0
  57. package/dist/beacon/beacon.schema.d.ts +41 -0
  58. package/dist/beacon/beacon.schema.js +48 -0
  59. package/dist/beacon/beacon.store.d.ts +29 -0
  60. package/dist/beacon/beacon.store.js +78 -0
  61. package/dist/better-auth/access.client-plugin.d.ts +75 -0
  62. package/dist/better-auth/access.client-plugin.js +133 -0
  63. package/dist/better-auth/access.plugin.d.ts +164 -0
  64. package/dist/better-auth/access.plugin.js +348 -0
  65. package/dist/better-auth/access.provider.d.ts +78 -0
  66. package/dist/better-auth/access.provider.js +100 -0
  67. package/dist/better-auth/index.d.ts +7 -0
  68. package/dist/better-auth/index.js +4 -0
  69. package/dist/better-auth/organization.bridge.d.ts +66 -0
  70. package/dist/better-auth/organization.bridge.js +144 -0
  71. package/dist/canonical-json.writer.d.ts +12 -0
  72. package/dist/canonical-json.writer.js +30 -0
  73. package/dist/cli/avaccess.bin.d.ts +2 -0
  74. package/dist/cli/avaccess.bin.js +26 -0
  75. package/dist/cli/avaccess.program.d.ts +15 -0
  76. package/dist/cli/avaccess.program.js +166 -0
  77. package/dist/cli/beacon-pins.file.d.ts +14 -0
  78. package/dist/cli/beacon-pins.file.js +62 -0
  79. package/dist/cli/beacon.loader.d.ts +20 -0
  80. package/dist/cli/beacon.loader.js +71 -0
  81. package/dist/cli/cli.context.d.ts +49 -0
  82. package/dist/cli/cli.context.js +66 -0
  83. package/dist/cli/diff.command.d.ts +2 -0
  84. package/dist/cli/diff.command.js +66 -0
  85. package/dist/cli/generate.command.d.ts +2 -0
  86. package/dist/cli/generate.command.js +82 -0
  87. package/dist/cli/keys.command.d.ts +2 -0
  88. package/dist/cli/keys.command.js +96 -0
  89. package/dist/cli/lock.file.d.ts +31 -0
  90. package/dist/cli/lock.file.js +181 -0
  91. package/dist/cli/module.loader.d.ts +13 -0
  92. package/dist/cli/module.loader.js +63 -0
  93. package/dist/cli/policies.diff.d.ts +16 -0
  94. package/dist/cli/policies.diff.js +83 -0
  95. package/dist/cli/pull.command.d.ts +2 -0
  96. package/dist/cli/pull.command.js +234 -0
  97. package/dist/cli/push.command.d.ts +2 -0
  98. package/dist/cli/push.command.js +59 -0
  99. package/dist/cli/registry.client.d.ts +63 -0
  100. package/dist/cli/registry.client.js +287 -0
  101. package/dist/cli/schema.command.d.ts +2 -0
  102. package/dist/cli/schema.command.js +60 -0
  103. package/dist/cli/serve.command.d.ts +6 -0
  104. package/dist/cli/serve.command.js +200 -0
  105. package/dist/cli/status.command.d.ts +2 -0
  106. package/dist/cli/status.command.js +31 -0
  107. package/dist/cli/translator.flag.d.ts +6 -0
  108. package/dist/cli/translator.flag.js +24 -0
  109. package/dist/cli/verify.command.d.ts +2 -0
  110. package/dist/cli/verify.command.js +40 -0
  111. package/dist/client/access-client.factory.d.ts +92 -0
  112. package/dist/client/access-client.factory.js +269 -0
  113. package/dist/client/access-verbs.schema.d.ts +66 -0
  114. package/dist/client/access-verbs.schema.js +159 -0
  115. package/dist/client/verb-rate.limiter.d.ts +116 -0
  116. package/dist/client/verb-rate.limiter.js +358 -0
  117. package/dist/foreign/foreign-facts.d.ts +30 -0
  118. package/dist/foreign/foreign-facts.js +75 -0
  119. package/dist/foreign/foreign.merger.d.ts +10 -0
  120. package/dist/foreign/foreign.merger.js +52 -0
  121. package/dist/foreign-references.check.d.ts +12 -0
  122. package/dist/foreign-references.check.js +134 -0
  123. package/dist/generator/client.emitter.d.ts +28 -0
  124. package/dist/generator/client.emitter.js +411 -0
  125. package/dist/generator/copied-modules.reader.d.ts +14 -0
  126. package/dist/generator/copied-modules.reader.js +80 -0
  127. package/dist/generator/namespace.facts.d.ts +28 -0
  128. package/dist/generator/namespace.facts.js +32 -0
  129. package/dist/generator/orm.translator.d.ts +48 -0
  130. package/dist/generator/orm.translator.js +29 -0
  131. package/dist/generator/prisma7/prisma-schema.reader.d.ts +9 -0
  132. package/dist/generator/prisma7/prisma-schema.reader.js +394 -0
  133. package/dist/generator/prisma7/prisma-where.translator.d.ts +72 -0
  134. package/dist/generator/prisma7/prisma-where.translator.js +136 -0
  135. package/dist/generator/prisma7/prisma7.translator.d.ts +2 -0
  136. package/dist/generator/prisma7/prisma7.translator.js +87 -0
  137. package/dist/generator/schema.emitter.d.ts +14 -0
  138. package/dist/generator/schema.emitter.js +23 -0
  139. package/dist/generator/tsconfig.reader.d.ts +44 -0
  140. package/dist/generator/tsconfig.reader.js +110 -0
  141. package/dist/generator/typescript-literal.writer.d.ts +5 -0
  142. package/dist/generator/typescript-literal.writer.js +42 -0
  143. package/dist/guardrails/guardrails-contract.d.ts +45 -0
  144. package/dist/guardrails/guardrails-contract.js +12 -0
  145. package/dist/guardrails/guardrails.builder.d.ts +48 -0
  146. package/dist/guardrails/guardrails.builder.js +32 -0
  147. package/dist/guardrails/guardrails.compiler.d.ts +10 -0
  148. package/dist/guardrails/guardrails.compiler.js +254 -0
  149. package/dist/guardrails/guardrails.composer.d.ts +7 -0
  150. package/dist/guardrails/guardrails.composer.js +95 -0
  151. package/dist/guardrails/guardrails.hash.d.ts +10 -0
  152. package/dist/guardrails/guardrails.hash.js +38 -0
  153. package/dist/index.d.ts +16 -0
  154. package/dist/index.js +6 -0
  155. package/dist/kiosk/kiosk-verbs.schema.d.ts +19 -0
  156. package/dist/kiosk/kiosk-verbs.schema.js +61 -0
  157. package/dist/kiosk/kiosk.plugin.d.ts +217 -0
  158. package/dist/kiosk/kiosk.plugin.js +877 -0
  159. package/dist/kiosk/kiosk.schema.d.ts +176 -0
  160. package/dist/kiosk/kiosk.schema.js +101 -0
  161. package/dist/kiosk/kiosk.store.d.ts +171 -0
  162. package/dist/kiosk/kiosk.store.js +478 -0
  163. package/dist/kiosk/lan-range.policy.d.ts +31 -0
  164. package/dist/kiosk/lan-range.policy.js +113 -0
  165. package/dist/kiosk/pin.policy.d.ts +9 -0
  166. package/dist/kiosk/pin.policy.js +143 -0
  167. package/dist/kiosk/session-use.marker.d.ts +4 -0
  168. package/dist/kiosk/session-use.marker.js +16 -0
  169. package/dist/lock/lock-contract.d.ts +38 -0
  170. package/dist/lock/lock-contract.js +67 -0
  171. package/dist/lock/lock.verifier.d.ts +27 -0
  172. package/dist/lock/lock.verifier.js +62 -0
  173. package/dist/mcp/agent-scope.gate.d.ts +11 -0
  174. package/dist/mcp/agent-scope.gate.js +75 -0
  175. package/dist/mcp/agent.grant.d.ts +36 -0
  176. package/dist/mcp/agent.grant.js +92 -0
  177. package/dist/mcp/mcp-options.d.ts +60 -0
  178. package/dist/mcp/mcp-options.js +72 -0
  179. package/dist/oauth/access-token.verifier.d.ts +66 -0
  180. package/dist/oauth/access-token.verifier.js +201 -0
  181. package/dist/oauth/oauth-provider.hardening.d.ts +62 -0
  182. package/dist/oauth/oauth-provider.hardening.js +261 -0
  183. package/dist/passwords/argon2id.hasher.d.ts +97 -0
  184. package/dist/passwords/argon2id.hasher.js +256 -0
  185. package/dist/passwords/node-rs-argon2.adapter.d.ts +25 -0
  186. package/dist/passwords/node-rs-argon2.adapter.js +42 -0
  187. package/dist/passwords/passwords.options.d.ts +79 -0
  188. package/dist/passwords/passwords.options.js +212 -0
  189. package/dist/policies-contract.d.ts +192 -0
  190. package/dist/policies-contract.js +8 -0
  191. package/dist/policies.compiler.d.ts +36 -0
  192. package/dist/policies.compiler.js +1358 -0
  193. package/dist/policies.decider.d.ts +103 -0
  194. package/dist/policies.decider.js +382 -0
  195. package/dist/policies.hash.d.ts +10 -0
  196. package/dist/policies.hash.js +53 -0
  197. package/dist/predicate.evaluator.d.ts +62 -0
  198. package/dist/predicate.evaluator.js +378 -0
  199. package/dist/random-secret.generator.d.ts +2 -0
  200. package/dist/random-secret.generator.js +15 -0
  201. package/dist/reference-reads.check.d.ts +12 -0
  202. package/dist/reference-reads.check.js +148 -0
  203. package/dist/registry/access.registry.d.ts +173 -0
  204. package/dist/registry/access.registry.js +865 -0
  205. package/dist/registry/beacon.ledger.d.ts +30 -0
  206. package/dist/registry/beacon.ledger.js +93 -0
  207. package/dist/registry/ownership.check.d.ts +54 -0
  208. package/dist/registry/ownership.check.js +215 -0
  209. package/dist/registry/registry.endpoints.d.ts +50 -0
  210. package/dist/registry/registry.endpoints.js +193 -0
  211. package/dist/registry/registry.key.d.ts +7 -0
  212. package/dist/registry/registry.key.js +13 -0
  213. package/dist/registry/registry.options.d.ts +13 -0
  214. package/dist/registry/registry.options.js +28 -0
  215. package/dist/registry/registry.refusal.d.ts +6 -0
  216. package/dist/registry/registry.refusal.js +11 -0
  217. package/dist/registry/registry.schema.d.ts +238 -0
  218. package/dist/registry/registry.schema.js +127 -0
  219. package/dist/resources/auth-tables.catalog.d.ts +91 -0
  220. package/dist/resources/auth-tables.catalog.js +102 -0
  221. package/dist/resources/auth-tables.guard.d.ts +95 -0
  222. package/dist/resources/auth-tables.guard.js +405 -0
  223. package/dist/scope.resolver.d.ts +138 -0
  224. package/dist/scope.resolver.js +512 -0
  225. package/dist/sha256.digest.d.ts +2 -0
  226. package/dist/sha256.digest.js +81 -0
  227. package/dist/standalone/access.server.d.ts +41 -0
  228. package/dist/standalone/access.server.js +301 -0
  229. package/dist/standalone/index.d.ts +1 -0
  230. package/dist/standalone/index.js +1 -0
  231. package/package.json +101 -3
  232. package/src/aventara-where.translator.ts +116 -0
  233. package/src/beacon/beacon.check.ts +204 -0
  234. package/src/canonical-json.writer.ts +51 -0
  235. package/src/generator/prisma7/prisma-where.translator.ts +241 -0
  236. package/src/policies-contract.ts +184 -0
  237. package/src/policies.decider.ts +650 -0
  238. package/src/predicate.evaluator.ts +574 -0
  239. package/src/scope.resolver.ts +791 -0
  240. package/src/sha256.digest.ts +85 -0
@@ -0,0 +1,66 @@
1
+ import type { AccessBuilder } from "../access.builder.js";
2
+ import type { AccessGuardrails, AccessGuardrailsJson } from "../guardrails/guardrails-contract.js";
3
+ import type { AccessLock } from "../lock/lock-contract.js";
4
+ import type { AccessPolicies, AccessPoliciesJson } from "../policies-contract.js";
5
+ import type { AccessClaimsAnswer, AccessClaimsDeclaration, AccessClaimsSource } from "./claims.mapper.js";
6
+ /** The fields each Resource governs, by Resource: what the rules' engine is typed with. */
7
+ type GovernedShape = {
8
+ readonly [resource: string]: readonly string[];
9
+ };
10
+ /** The claims a rules principal type `R` reads, by name. */
11
+ type ClaimNamesOf<R> = R extends {
12
+ readonly claims?: infer C;
13
+ } ? keyof NonNullable<C> & string : never;
14
+ /**
15
+ * `policies.claims`, held to the rules: a claim the rules' principal type reads and
16
+ * the declaration lacks is a type error here, naming it.
17
+ */
18
+ type DeclaredFor<R, C extends AccessClaimsDeclaration> = [
19
+ Exclude<ClaimNamesOf<R>, keyof C>
20
+ ] extends [never] ? C : C & {
21
+ readonly [K in Exclude<ClaimNamesOf<R>, keyof C>]: `the rules read the claim "${K}": declare it here, or correct the rules' principal type`;
22
+ };
23
+ /**
24
+ * The rules an instance evaluates: `definePolicies(model)…` as written, or its
25
+ * compiled file (typed, or imported as JSON as `avaccess pull` wrote it).
26
+ */
27
+ export type AccessRules<R, Gov extends GovernedShape> = AccessBuilder<any, R, any, Gov> | AccessPolicies<Gov> | AccessPoliciesJson<Gov>;
28
+ /** The `policies` block. */
29
+ export type AccessPoliciesOptions<C extends AccessClaimsDeclaration, R, Gov extends GovernedShape> = {
30
+ /** The rules this instance evaluates: the builder (its principal type is checked here) or its compiled file. */
31
+ readonly rules: AccessRules<R, Gov>;
32
+ /** The global claims a token carries beside `sub`, by type: `{ role: "string", banned: "boolean" }`. */
33
+ readonly claims: DeclaredFor<R, C>;
34
+ /**
35
+ * A user's claims, when a token is issued: every declared boolean claim, the
36
+ * others where the user has them. Without it, each declared claim is read from
37
+ * the user's field of the same name.
38
+ */
39
+ readonly claimsOf?: (source: AccessClaimsSource) => AccessClaimsAnswer<C> | Promise<AccessClaimsAnswer<C>>;
40
+ /**
41
+ * The org's guardrails, as pulled from the registry (`aventara-access/guardrails@1`):
42
+ * deny-only rules the engine adds on top of `rules`. They only narrow. Every claim
43
+ * they compare must be declared in `claims`.
44
+ */
45
+ readonly guardrails?: AccessGuardrails | AccessGuardrailsJson;
46
+ /**
47
+ * The project's `avAccess.lock.json`, as `avaccess pull` wrote it: the instance
48
+ * refuses to start (`ACCESS_LOCK_MISMATCH`) unless `guardrails`, and `rules` when
49
+ * they are a pulled file, hash to what the lock pins.
50
+ */
51
+ readonly lock?: AccessLock;
52
+ /**
53
+ * `true`: refuse to start without `lock` (`ACCESS_LOCK_MISMATCH`), so a deploy that
54
+ * lost its `avAccess.lock.json` fails at startup instead of running unpinned files;
55
+ * typed rules are then held to the lock's policies hash too. Recommended in
56
+ * production.
57
+ */
58
+ readonly requireLock?: boolean;
59
+ /**
60
+ * How long a token lives, in seconds: from 300 to 900 (5 to 15 minutes), 900 by
61
+ * default. A claim that must take effect soon (`banned`, `suspended`) reaches every
62
+ * service with the user's next token, so this is the longest such a change waits.
63
+ */
64
+ readonly tokenTtl?: number;
65
+ };
66
+ export {};
@@ -0,0 +1,5 @@
1
+ // The `policies` block's types, which `createAccess` and `aventaraAccess()` share: the
2
+ // rules, and the claims they read, held to each other. Both are published from
3
+ // `/auth`; what they are built from stays in this module, so a consumer's
4
+ // declaration emit writes it out rather than naming a module it cannot import.
5
+ export {};
@@ -0,0 +1,35 @@
1
+ /** What an {@link AccessError} refuses. */
2
+ export type AccessErrorCode =
3
+ /** `better-auth` is missing, or outside Access's range (`~1.7.12`), as is an OAuth provider or `cimd()` Access reads. */
4
+ "ACCESS_BETTER_AUTH_VERSION"
5
+ /** A claim the rules read, or one a token carries, that `policies.claims` does not declare. */
6
+ | "ACCESS_CLAIMS_UNDECLARED"
7
+ /** `betterAuth.plugins` holds a plugin `createAccess` installs itself (under any case or spacing of its id), or one that defines `jwt()`'s endpoints or Access's `me` route. */
8
+ | "ACCESS_PLUGIN_DUPLICATE"
9
+ /** An Access block (`policies`, `principal`, `profile`, `registry`, `audit`, `resources`, `passwords`) is not one `createAccess` accepts; `passwords` set beside Better Auth's own `emailAndPassword.password` hook, or argon2id asked of a runtime without `crypto.argon2` or `@node-rs/argon2`; the rules grant what the `resources` block leaves closed; a claim would be read from a field the user can set; Better Auth has no base URL to fix the tokens' issuer; the session cookie is `sameSite: "none"` without trusted origins; Better Auth off its Prisma adapter without `resources.authTables`, or an opened table's secret column not found; or `principal` returned one object for two users. */
10
+ | "ACCESS_OPTIONS_INVALID"
11
+ /** A pushed file names a Resource its namespace does not own, or the org's guardrails file grants. */
12
+ | "ACCESS_OWNERSHIP"
13
+ /** A registry key that is wrong, revoked or rotated out, or one whose kind or namespace does not fit the call. */
14
+ | "ACCESS_KEY_REFUSED"
15
+ /** A pushed file is not a policies file, or the org's guardrails are not a guardrails file, the engine would run from. */
16
+ | "ACCESS_POLICIES_INVALID"
17
+ /** A namespace name that is not one, a namespace the registry does not have (a guardrail's included), or one it has already. */
18
+ | "ACCESS_NAMESPACE"
19
+ /** A stored revision no longer hashes to the hash it was pushed under: it was changed outside the registry. */
20
+ | "ACCESS_REVISION_CHANGED"
21
+ /** A pulled file no longer hashes to the hash `avAccess.lock.json` pins for it, or the engine was handed files the lock does not pin. */
22
+ | "ACCESS_LOCK_MISMATCH"
23
+ /** A Better Auth table `resources` opens is missing: Better Auth has none (its plugin is not installed), or the rules' schema has no Resource for it. */
24
+ | "ACCESS_RESOURCE_MISSING"
25
+ /** A question the engine cannot answer as asked: a `fieldsOf` question without `access: "read"` or `access: "write"`, or with an `action` that does not fit it; or a `hosted` call whose `held` is not a list of Resource names. */
26
+ | "ACCESS_QUESTION_INVALID"
27
+ /** A file reads another namespace's Resources as `foreign` while the two are on different databases: the reader's view of the owner's beacon is not the one the owner pushed, the owner has pushed none, or the push carries none. */
28
+ | "ACCESS_FOREIGN_CROSS_DATABASE"
29
+ /** A beacon that is not what it should be: at startup an owner's row, read through the service's own connection, is missing or does not hash to the lock's pin (or was not checked yet); at push a namespace's own beacon is another namespace's; or a beacon row holds no beacon. */
30
+ | "ACCESS_BEACON_MISMATCH";
31
+ /** A refusal by `createAccess`, the instance it built, its registry, or an engine checking its lock or a question: `code` says which, the message what to change. */
32
+ export declare class AccessError extends Error {
33
+ readonly code: AccessErrorCode;
34
+ constructor(code: AccessErrorCode, message: string);
35
+ }
@@ -0,0 +1,11 @@
1
+ // The one error `createAccess` and the instance it builds throw. Each refusal has a
2
+ // code a program can branch on and a message that says what to change.
3
+ /** A refusal by `createAccess`, the instance it built, its registry, or an engine checking its lock or a question: `code` says which, the message what to change. */
4
+ export class AccessError extends Error {
5
+ code;
6
+ constructor(code, message) {
7
+ super(`Aventara Access: ${message}`);
8
+ this.name = "AccessError";
9
+ this.code = code;
10
+ }
11
+ }
@@ -0,0 +1,273 @@
1
+ import type { Auth, BetterAuthOptions, BetterAuthPlugin } from "better-auth";
2
+ import type { jwt } from "better-auth/plugins/jwt";
3
+ import type { AccessEngine } from "../access.engine.js";
4
+ import type { AccessAuditOptions } from "../audit/audit-event.js";
5
+ import type { AccessBeaconStore } from "../beacon/beacon.store.js";
6
+ import { type AccessKiosk } from "../kiosk/kiosk.plugin.js";
7
+ import { type AccessMcpAuthorization, type AccessMcpOptions } from "../mcp/mcp-options.js";
8
+ import { type AccessPasswordsOptions } from "../passwords/passwords.options.js";
9
+ import { type AccessRegistry } from "../registry/access.registry.js";
10
+ import { type AccessRegistryOptions } from "../registry/registry.options.js";
11
+ import { type AccessResourcesOptions } from "../resources/auth-tables.guard.js";
12
+ import type { AccessPoliciesOptions } from "./access-options.js";
13
+ import { type AccessClaimsDeclaration, type AccessClaimsOf, type AccessIdentity } from "./claims.mapper.js";
14
+ import { type AccessProfileOptions } from "./profile.policy.js";
15
+ export type { AccessPoliciesOptions, AccessRules, } from "./access-options.js";
16
+ type GovernedShape = {
17
+ readonly [resource: string]: readonly string[];
18
+ };
19
+ /** The headers of a request, as the framework hands them to `state`. */
20
+ type RequestHeaders = {
21
+ get(name: string): string | null;
22
+ has(name: string): boolean;
23
+ forEach(callback: (value: string, name: string) => void): void;
24
+ };
25
+ /**
26
+ * The principal (`me`) an instance hands the engine: the rules' principal type when
27
+ * the rules are the builder, else what `principal` returns (by default the identity).
28
+ */
29
+ type AccessPrincipalOf<R, M> = unknown extends R ? M : R;
30
+ /**
31
+ * The request's principal (`me`) from a verified identity: the app maps `sub` to its
32
+ * own profile, and `null` leaves the caller anonymous. With the builder as the rules,
33
+ * it returns their principal type.
34
+ */
35
+ type AccessPrincipalFunction<C extends AccessClaimsDeclaration, R, M> = (identity: AccessIdentity<C>) => (unknown extends R ? M : NoInfer<R>) | null | Promise<(unknown extends R ? M : NoInfer<R>) | null>;
36
+ /**
37
+ * The `principal` option: optional while the identity (`{ sub, claims }`) is itself
38
+ * the rules' principal type, and required when the rules are typed with another.
39
+ */
40
+ type AccessPrincipalOption<C extends AccessClaimsDeclaration, R, M> = [
41
+ AccessIdentity<C>
42
+ ] extends [R] ? {
43
+ /** The request's principal (`me`) from the verified identity; without it, `me` is the identity, `{ sub, claims }`. */
44
+ readonly principal?: AccessPrincipalFunction<C, R, M>;
45
+ } : {
46
+ /** The request's principal (`me`) from the verified identity, typed as the rules' principal. */
47
+ readonly principal: AccessPrincipalFunction<C, R, M>;
48
+ };
49
+ /**
50
+ * The plugins `createAccess` installs itself, by id, as a sentence names each.
51
+ */
52
+ declare const INSTALLED_PLUGINS: {
53
+ readonly "aventara-access": "aventaraAccess()";
54
+ readonly jwt: "jwt()";
55
+ };
56
+ type InstalledPluginId = keyof typeof INSTALLED_PLUGINS;
57
+ /** One `betterAuth.plugins` entry, or the sentence that refuses it. */
58
+ type AccessPluginEntry<E> = E extends {
59
+ readonly id: infer I extends InstalledPluginId;
60
+ } ? `createAccess installs ${(typeof INSTALLED_PLUGINS)[I]} itself: remove it from betterAuth.plugins` : E;
61
+ /** Whether a plugin list holds one `createAccess` installs itself. */
62
+ type HoldsInstalled<L extends readonly unknown[]> = true extends {
63
+ [K in keyof L]: L[K] extends {
64
+ readonly id: InstalledPluginId;
65
+ } ? true : false;
66
+ }[number] ? true : false;
67
+ /**
68
+ * The `betterAuth` block: Better Auth's options as given. A plugin `createAccess`
69
+ * installs itself is a type error at that plugin, which reads as the sentence to fix it.
70
+ */
71
+ type AccessBetterAuthBlock<O extends BetterAuthOptions> = O extends {
72
+ readonly plugins?: infer L extends readonly unknown[];
73
+ } ? HoldsInstalled<L> extends true ? Omit<O, "plugins"> & {
74
+ readonly plugins: {
75
+ [K in keyof L]: AccessPluginEntry<L[K]>;
76
+ };
77
+ } : O : O;
78
+ /** Better Auth's options as `createAccess` builds Better Auth with them: the app's, and `jwt()`. */
79
+ export type AccessBetterAuthOptions<O extends BetterAuthOptions> = Omit<O, "plugins"> & {
80
+ plugins: [
81
+ ...(O extends {
82
+ readonly plugins?: infer L extends readonly unknown[];
83
+ } ? L : []),
84
+ ReturnType<typeof jwt>,
85
+ BetterAuthPlugin & {
86
+ readonly id: "aventara-access";
87
+ }
88
+ ];
89
+ };
90
+ /** `createAccess`'s options. */
91
+ export type AccessOptions<O extends BetterAuthOptions, C extends AccessClaimsDeclaration, R, Gov extends GovernedShape, M, E extends boolean = false, X extends AccessMcpOptions | undefined = AccessMcpOptions | undefined> = {
92
+ /** Better Auth's options, exactly as `betterAuth({...})` takes them. `createAccess` installs `jwt()` itself. */
93
+ readonly betterAuth: AccessBetterAuthBlock<O>;
94
+ /**
95
+ * The shape of app this instance serves: `web` (the default), `service` (bearer
96
+ * tokens only; no caller is handed a new session) or `kiosk` (`web`, plus staff
97
+ * switching by PIN on enrolled devices, each PIN session bound to its device and
98
+ * locked when idle).
99
+ */
100
+ readonly profile?: AccessProfileOptions<C>;
101
+ /**
102
+ * The policy registry: namespaces, their keys, pushed files and the org's
103
+ * guardrails, in tables Better Auth's adapter stores and routes `access.handler`
104
+ * serves under `/access/v1/namespaces`. Off by default: no tables, no routes.
105
+ */
106
+ readonly registry?: AccessRegistryOptions<E>;
107
+ /**
108
+ * The audit log of sign-ins and `can` decisions: `true` writes the `accessAudit`
109
+ * table (Better Auth's `generate`/`migrate` create it), `{ sink }` hands each event
110
+ * to the app instead. Off by default.
111
+ */
112
+ readonly audit?: AccessAuditOptions;
113
+ /**
114
+ * Which of Better Auth's tables are Resources of the rules: `users` (`user`,
115
+ * `session`, `account`) and `members` (the organization plugin's `member`, and its
116
+ * `organization`). Every other table of Better Auth's is closed, and no grant ever
117
+ * opens a secret column. Writes through Aventara skip Better Auth's hooks and
118
+ * caches, so they are limited to a user's `role` and to memberships.
119
+ */
120
+ readonly resources?: AccessResourcesOptions;
121
+ /**
122
+ * How passwords are hashed: argon2id at a named parameter profile,
123
+ * `"owasp-minimum"` (the default) or `"rfc9106-low-memory"`, and with
124
+ * `legacyScrypt: true` Better Auth's scrypt hashes accepted. A hash at another
125
+ * profile, or scrypt, is rehashed at the profile at its account's next sign-in.
126
+ * Without it, and without `betterAuth.emailAndPassword.password`, the
127
+ * default profile is used; an app that sets that hook hashes its own way, and may
128
+ * not set this too.
129
+ */
130
+ readonly passwords?: AccessPasswordsOptions;
131
+ /**
132
+ * Access as the authorization layer of an MCP endpoint (the framework's `mcp`):
133
+ * `{ resource }`, the endpoint's URL. The tokens come from Better Auth's OAuth
134
+ * provider (`@better-auth/oauth-provider`), which goes in
135
+ * `betterAuth.plugins` with the endpoint among its `resources`; `access.mcp` is the
136
+ * framework's `mcp.authorization`. Not on the `service` profile.
137
+ */
138
+ readonly mcp?: X & {
139
+ readonly [K in Exclude<keyof X, keyof AccessMcpOptions>]: never;
140
+ };
141
+ /**
142
+ * The service's own audience, an opt-in (RFC 8707): its URL, as a client names it
143
+ * when it asks Better Auth's OAuth provider for a token for this service
144
+ * (`resource`). With it, a bearer token is taken only when it is the provider's
145
+ * access token addressed to this audience alone; the one-org token `GET /token`
146
+ * issues (its audience the issuer) is refused. Session cookies are read as before.
147
+ * Off by default. The provider goes in `betterAuth.plugins` with the audience among
148
+ * its `resources`. Not on the `service` profile.
149
+ */
150
+ readonly audience?: string;
151
+ } & AccessPoliciesMember<C, R, Gov, E> & AccessPrincipalOption<C, R, M>;
152
+ /**
153
+ * The `policies` block's place in the options: required, except on an instance that
154
+ * serves the registry (`registry: { enabled: true }`), which may have no rules of its
155
+ * own: it then answers every policy question with a deny.
156
+ */
157
+ type AccessPoliciesMember<C extends AccessClaimsDeclaration, R, Gov extends GovernedShape, E extends boolean> = [E] extends [true] ? {
158
+ /** The rules and the claims they read. A registry-only server may leave it out: no claim beside `sub`, and every policy question denied. */
159
+ readonly policies?: AccessPoliciesOptions<C, R, Gov>;
160
+ } : {
161
+ /** The rules and the claims they read. */
162
+ readonly policies: AccessPoliciesOptions<C, R, Gov>;
163
+ };
164
+ export type { AccessRegistryOptions };
165
+ /** `access.registry`: the operator's API when the registry is on, absent when it is off. */
166
+ type AccessRegistryMember<E extends boolean> = [E] extends [true] ? {
167
+ /** The registry's operator API: namespaces, keys and the org's guardrails. */
168
+ readonly registry: AccessRegistry;
169
+ } : [E] extends [false] ? {
170
+ readonly registry?: undefined;
171
+ } : {
172
+ readonly registry?: AccessRegistry | undefined;
173
+ };
174
+ /** What `createAccess` returns: Better Auth's surface, the policy engine and the request state. */
175
+ export type Access<O extends BetterAuthOptions, C extends AccessClaimsDeclaration, Gov extends GovernedShape, M, E extends boolean = false, P extends boolean = false> = {
176
+ /** Better Auth's request handler, with Access's routes: mount it where you would mount Better Auth's. */
177
+ readonly handler: Auth<AccessBetterAuthOptions<O>>["handler"];
178
+ /** Better Auth's server API, as `auth.api`. */
179
+ readonly api: Auth<AccessBetterAuthOptions<O>>["api"];
180
+ /** The options Better Auth is built with: the `betterAuth` block plus the plugins `createAccess` installs. */
181
+ readonly options: AccessBetterAuthOptions<O>;
182
+ /** Types only, as Better Auth's `$Infer`: `typeof access.$Infer.Me` is the principal. */
183
+ readonly $Infer: {
184
+ readonly Session: Auth<AccessBetterAuthOptions<O>>["$Infer"]["Session"];
185
+ readonly Me: M;
186
+ readonly Claims: AccessClaimsOf<C>;
187
+ };
188
+ /** The policy engine, asked about every client and agent request. */
189
+ readonly policy: AccessEngine<Gov>;
190
+ /**
191
+ * The Access server's own beacon row in `_aventara_beacon`, through Better Auth's
192
+ * adapter, on an instance with the registry on whose rules name a namespace: the
193
+ * store `avaccess push --beacon` loads to push it, and `policy.checkBeacons` reads
194
+ * through.
195
+ */
196
+ readonly beacon?: AccessBeaconStore;
197
+ /**
198
+ * The kiosk profile's operator API, for the app's own server (present on that
199
+ * profile only, and no route opens it): `listDevices()` and `revokeDevice(id)`.
200
+ * Another user's PIN is set through Better Auth's server-only endpoint,
201
+ * `access.api.kioskSetUserPin({ body: { userId, pin } })`.
202
+ */
203
+ readonly kiosk?: AccessKiosk;
204
+ /** A request's state: `me`, from its bearer token or (profiles `web` and `kiosk`) its session cookie, else `null`. */
205
+ state(input: {
206
+ readonly headers: RequestHeaders;
207
+ readonly request?: unknown;
208
+ }): Promise<{
209
+ readonly me: M | null;
210
+ }>;
211
+ /**
212
+ * What the framework's `$access` needs: where Access is mounted (`url`, from
213
+ * Better Auth's `baseURL` and `basePath`), and each verb this instance serves,
214
+ * with its route under `url`, the JSON Schema of its arguments and of its result
215
+ * (`me`'s: the token identity, `{ sub, claims }`, with the declared claims), and
216
+ * its server call. `call` runs the verb in-process through Better Auth's API with
217
+ * the request's headers, held to the same checks as the route (origin, profile,
218
+ * audit), so a cookie plugin such as `nextCookies()` sets the browser's cookie
219
+ * from a Server Action. A verb the instance does not serve is absent: `signIn`,
220
+ * `signUp` and `resetPassword` need `emailAndPassword`, the `service` profile
221
+ * has no `signIn` or `signUp`, and only the `kiosk` profile has its verbs:
222
+ * `switchUser` (`{ userId, pin }`) and `lock` on an enrolled device, `setPin`
223
+ * (`{ pin }`) from a fresh session opened with full credentials, and
224
+ * `enrollDevice` (`{ name }`) and `revokeDevice` (`{ deviceId }`) from one
225
+ * `canEnrollDevice` allows.
226
+ */
227
+ readonly client: {
228
+ /** Where the app mounted Access: absolute, or root-relative (`"/api/auth"`) when Better Auth's base URL follows the request. */
229
+ readonly url: string;
230
+ readonly verbs: {
231
+ readonly [V in "signIn" | "signUp" | "signOut" | "resetPassword" | "me" | "switchUser" | "lock" | "setPin" | "enrollDevice" | "revokeDevice"]?: {
232
+ readonly method: "GET" | "POST";
233
+ /** Under `url`: `"/sign-in/email"`. */
234
+ readonly path: string;
235
+ /** The JSON Schema of the arguments; absent when the verb takes none. */
236
+ readonly args?: {
237
+ readonly [key: string]: unknown;
238
+ };
239
+ /** The JSON Schema of the result (`me`: of the non-null value). */
240
+ readonly result: {
241
+ readonly [key: string]: unknown;
242
+ };
243
+ /** The verb, run in-process with the request's headers: its result, cut to `result`. */
244
+ call(input: {
245
+ readonly args: unknown;
246
+ readonly headers: RequestHeaders;
247
+ readonly request?: unknown;
248
+ }): Promise<unknown>;
249
+ };
250
+ };
251
+ };
252
+ } & AccessRegistryMember<E> & AccessMcpMember<C, P>;
253
+ /** Whether an `mcp` block is given: `true`, `false`, or `boolean` when the types cannot tell. */
254
+ type McpGiven<X> = [X] extends [undefined] ? false : [X] extends [AccessMcpOptions] ? true : boolean;
255
+ /** `access.mcp`: the framework's `mcp.authorization` when `mcp` is given, absent when it is not. */
256
+ type AccessMcpMember<C extends AccessClaimsDeclaration, P extends boolean> = [
257
+ P
258
+ ] extends [true] ? {
259
+ /** The framework's `mcp.authorization`: `mcp: { path: "/mcp", authorization: access.mcp }`. */
260
+ readonly mcp: AccessMcpAuthorization<AccessClaimsOf<C>>;
261
+ } : [P] extends [false] ? {
262
+ readonly mcp?: undefined;
263
+ } : {
264
+ readonly mcp?: AccessMcpAuthorization<AccessClaimsOf<C>> | undefined;
265
+ };
266
+ /**
267
+ * Builds an Access instance: Better Auth (from the `betterAuth` block, with `jwt()`
268
+ * and the Access plugin installed), the policy engine (from `policies.rules`) and
269
+ * the request state the framework's `access` option reads. It mounts nothing and
270
+ * opens no connection; `better-auth` is loaded here, and must be the exact version
271
+ * Access is built against.
272
+ */
273
+ export declare function createAccess<O extends BetterAuthOptions, const C extends AccessClaimsDeclaration, R = unknown, Gov extends GovernedShape = Record<never, never>, M = AccessIdentity<C>, const E extends boolean = false, X extends AccessMcpOptions | undefined = undefined>(options: AccessOptions<O, C, R, Gov, M, E, X>): Access<O, C, Gov, AccessPrincipalOf<R, M>, E, McpGiven<X>>;