@company-semantics/contracts 39.7.0 → 39.8.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@company-semantics/contracts",
3
- "version": "39.7.0",
3
+ "version": "39.8.0",
4
4
  "private": false,
5
5
  "repository": {
6
6
  "type": "git",
package/src/index.ts CHANGED
@@ -907,6 +907,17 @@ export type {
907
907
  DisableSecretRequest,
908
908
  } from "./security/index";
909
909
 
910
+ // Auth token storage/entropy policy (PRD-00901)
911
+ // @see src/security/token-policy.ts — single source for the runtime issuance
912
+ // path and the secure-token-generation CI guard
913
+ export { AUTH_TOKEN_POLICY_REQUIREMENTS } from "./security/index";
914
+ export type {
915
+ TokenStorageFormat,
916
+ TokenPolicyConformance,
917
+ TokenPolicyRequirement,
918
+ AuthTokenPolicyClass,
919
+ } from "./security/index";
920
+
910
921
  // Analytics response metadata (shared vocabulary for OLTP/OLAP separation)
911
922
  // @see ADR-CTRL-053 for design rationale
912
923
  export type {
@@ -19,3 +19,11 @@ export type {
19
19
  RotateSecretRequest,
20
20
  DisableSecretRequest,
21
21
  } from "./org-secrets";
22
+
23
+ export { AUTH_TOKEN_POLICY_REQUIREMENTS } from "./token-policy";
24
+ export type {
25
+ TokenStorageFormat,
26
+ TokenPolicyConformance,
27
+ TokenPolicyRequirement,
28
+ AuthTokenPolicyClass,
29
+ } from "./token-policy";
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Declared storage and entropy policy for auth-bearing tokens.
3
+ *
4
+ * This is the single source consumed by BOTH the runtime issuance path and the
5
+ * secure-token-generation CI guard. A declaration with no enforcing consumer is
6
+ * the defect class this module exists to close.
7
+ *
8
+ * Every field states what an implementation MUST satisfy. None of them describe
9
+ * what the code does today — that is `conformance`, and it is mandatory per
10
+ * class. Keeping the two apart is the point: a requirement record that reads as
11
+ * a description silently re-asserts the guarantee it was written to obtain, and
12
+ * is the same declaration-without-enforcement defect wearing a different hat.
13
+ */
14
+ export type TokenStorageFormat = "hashed" | "hmac-signed" | "encrypted";
15
+
16
+ /**
17
+ * Whether every known issuance site already satisfies the declared requirement.
18
+ *
19
+ * `enforced` — no known site violates it.
20
+ * `unmet` — at least one known site violates it; `gap` names what is wrong.
21
+ *
22
+ * This is NOT a suppression and confers no exemption. The requirement holds
23
+ * either way and the secure-token-generation guard reports the violating sites
24
+ * regardless — the field exists so the canonical record cannot be read as
25
+ * asserting a guarantee the implementation has not yet earned.
26
+ */
27
+ export type TokenPolicyConformance =
28
+ | { readonly status: "enforced" }
29
+ | { readonly status: "unmet"; readonly gap: string };
30
+
31
+ export interface TokenPolicyRequirement {
32
+ /** Minimum entropy the raw token must carry, in bits. */
33
+ readonly minEntropyBits: number;
34
+ /** Algorithm the stored representation must be derived with. */
35
+ readonly hashAlgorithm: string;
36
+ /**
37
+ * How the token must be persisted. Never 'plaintext' — that is not a member,
38
+ * because plaintext is never an acceptable requirement. A class that IS
39
+ * persisted in plaintext today says so through `conformance`, which is why
40
+ * the union does not need to express it.
41
+ */
42
+ readonly storageFormat: TokenStorageFormat;
43
+ /**
44
+ * Whether the implementation currently meets the requirement above. Required,
45
+ * not optional: an omitted status would default to an unearned claim, which
46
+ * is exactly the drift this record exists to surface.
47
+ */
48
+ readonly conformance: TokenPolicyConformance;
49
+ /**
50
+ * Identifier / function-name patterns that bind a call site to this policy
51
+ * class. Heuristic only: the AUTHORITATIVE binding is the explicit policy
52
+ * argument passed at the generation site. These patterns exist so the guard
53
+ * can flag an UNCLASSIFIED site, never to silently classify one.
54
+ */
55
+ readonly contextPatterns: readonly string[];
56
+ }
57
+
58
+ export const AUTH_TOKEN_POLICY_REQUIREMENTS = {
59
+ SessionToken: {
60
+ minEntropyBits: 256,
61
+ hashAlgorithm: "SHA-256",
62
+ storageFormat: "hashed",
63
+ contextPatterns: ["session"],
64
+ conformance: {
65
+ status: "unmet",
66
+ gap:
67
+ "Minted with randomUUID() (122 bits) and persisted verbatim: sessions.token " +
68
+ "holds the cookie value itself, and lookup is raw equality against it.",
69
+ },
70
+ },
71
+ ChatShareToken: {
72
+ minEntropyBits: 256,
73
+ hashAlgorithm: "SHA-256",
74
+ storageFormat: "hashed",
75
+ contextPatterns: ["share"],
76
+ conformance: {
77
+ status: "unmet",
78
+ gap:
79
+ "Minted with randomBytes(32) and persisted verbatim: chat_shares.token holds " +
80
+ "the share-URL value itself, and lookup is raw equality against it.",
81
+ },
82
+ },
83
+ InviteToken: {
84
+ minEntropyBits: 256,
85
+ hashAlgorithm: "SHA-256",
86
+ storageFormat: "hashed",
87
+ contextPatterns: ["invite"],
88
+ conformance: { status: "enforced" },
89
+ },
90
+ OAuthStateToken: {
91
+ minEntropyBits: 128,
92
+ hashAlgorithm: "HMAC-SHA256",
93
+ storageFormat: "hmac-signed",
94
+ contextPatterns: ["state", "nonce"],
95
+ conformance: { status: "enforced" },
96
+ },
97
+ OTPCode: {
98
+ minEntropyBits: 20,
99
+ hashAlgorithm: "bcrypt",
100
+ storageFormat: "hashed",
101
+ contextPatterns: ["otp", "loginCode"],
102
+ conformance: { status: "enforced" },
103
+ },
104
+ OAuthTokenEncryption: {
105
+ minEntropyBits: 256,
106
+ hashAlgorithm: "AES-256-GCM",
107
+ storageFormat: "encrypted",
108
+ contextPatterns: ["tokenEncryption"],
109
+ conformance: { status: "enforced" },
110
+ },
111
+ } as const satisfies Record<string, TokenPolicyRequirement>;
112
+
113
+ export type AuthTokenPolicyClass = keyof typeof AUTH_TOKEN_POLICY_REQUIREMENTS;