@company-semantics/contracts 2.4.0 → 2.5.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": "2.4.0",
3
+ "version": "2.5.0",
4
4
  "private": false,
5
5
  "repository": {
6
6
  "type": "git",
@@ -99,7 +99,14 @@ const AclEntrySchema = z.object({
99
99
  });
100
100
 
101
101
  const AccessReasonSchema = z.object({
102
- source: z.enum(['org_rbac', 'sharing_policy', 'unit_baseline', 'acl_grant', 'doc_ownership']),
102
+ source: z.enum([
103
+ 'org_rbac',
104
+ 'sharing_policy',
105
+ 'unit_baseline',
106
+ 'unit_delegation',
107
+ 'acl_grant',
108
+ 'doc_ownership',
109
+ ]),
103
110
  detail: z.string(),
104
111
  });
105
112
 
package/src/index.ts CHANGED
@@ -663,6 +663,26 @@ export { openApiRoutes, type OpenApiRoute, type OpenApiMethod } from './generate
663
663
  export type { Secret } from './security/index'
664
664
  export { wrapSecret, unwrapSecret } from './security/index'
665
665
 
666
+ // Org Secrets DTO schemas (PRD-00629) — masked-prefix-only, no value field
667
+ export {
668
+ UsageClassSchema,
669
+ OrgSecretsActionSchema,
670
+ SecretValueStringSchema,
671
+ OrgSecretSummarySchema,
672
+ CreateSecretRequestSchema,
673
+ RotateSecretRequestSchema,
674
+ DisableSecretRequestSchema,
675
+ } from './security/org-secrets'
676
+ export type {
677
+ UsageClass,
678
+ OrgSecretsAction,
679
+ SecretValueString,
680
+ OrgSecretSummary,
681
+ CreateSecretRequest,
682
+ RotateSecretRequest,
683
+ DisableSecretRequest,
684
+ } from './security/org-secrets'
685
+
666
686
  // Analytics response metadata (shared vocabulary for OLTP/OLAP separation)
667
687
  // @see ADR-CTRL-053 for design rationale
668
688
  export type { AnalyticsBackend, AnalyticsResponseMeta } from './types/analytics'
@@ -1,2 +1,21 @@
1
1
  export type { Secret } from './secret';
2
2
  export { wrapSecret, unwrapSecret } from './secret';
3
+
4
+ export {
5
+ UsageClassSchema,
6
+ OrgSecretsActionSchema,
7
+ SecretValueStringSchema,
8
+ OrgSecretSummarySchema,
9
+ CreateSecretRequestSchema,
10
+ RotateSecretRequestSchema,
11
+ DisableSecretRequestSchema,
12
+ } from './org-secrets';
13
+ export type {
14
+ UsageClass,
15
+ OrgSecretsAction,
16
+ SecretValueString,
17
+ OrgSecretSummary,
18
+ CreateSecretRequest,
19
+ RotateSecretRequest,
20
+ DisableSecretRequest,
21
+ } from './org-secrets';
@@ -0,0 +1,100 @@
1
+ /**
2
+ * Org Secrets — DTO schemas
3
+ *
4
+ * Zod schemas for the org_secrets surface (PRD-00629). The contracts package
5
+ * defines what admin clients may observe and submit. The decrypted credential
6
+ * value is intentionally absent from every surface here — the only
7
+ * credential-derived field exposed is `maskedPrefix`.
8
+ *
9
+ * Servers receiving plaintext (CreateSecretRequest / RotateSecretRequest)
10
+ * are expected to wrap it with {@link Secret} from `./secret` before storage,
11
+ * and never re-emit it to clients.
12
+ */
13
+ import { z } from 'zod';
14
+
15
+ /**
16
+ * Classification of how a credential is consumed at runtime. Drives downstream
17
+ * authorization and audit categorization.
18
+ */
19
+ export const UsageClassSchema = z.enum(['AI_PROVIDER', 'WEBHOOK_SIGNING', 'GENERIC']);
20
+ export type UsageClass = z.infer<typeof UsageClassSchema>;
21
+
22
+ /**
23
+ * Auditable lifecycle and access events for an org secret. Used by the audit
24
+ * trail and observability surfaces; the schema is the closed enumeration.
25
+ */
26
+ export const OrgSecretsActionSchema = z.enum([
27
+ 'created',
28
+ 'rotated',
29
+ 'disabled',
30
+ 'enabled',
31
+ 'access_denied',
32
+ 'explicit_export',
33
+ 'unusual_access',
34
+ ]);
35
+ export type OrgSecretsAction = z.infer<typeof OrgSecretsActionSchema>;
36
+
37
+ /**
38
+ * Branded plaintext credential string. Bounded so accidental logs do not leak
39
+ * megabytes; branded to discourage propagation through generic string flows.
40
+ * Servers must wrap with Secret<T> before storage and never echo it back.
41
+ */
42
+ export const SecretValueStringSchema = z
43
+ .string()
44
+ .min(1)
45
+ .max(8192)
46
+ .brand<'SecretValueString'>();
47
+ export type SecretValueString = z.infer<typeof SecretValueStringSchema>;
48
+
49
+ /**
50
+ * Admin-visible summary of an `org_secrets` row. The decrypted value is
51
+ * intentionally absent — `maskedPrefix` is the only credential-derived field
52
+ * exposed by this surface (INV-PRD-00629: no value in summary).
53
+ *
54
+ * `usageCount` is serialized as a string for cross-driver bigint safety.
55
+ */
56
+ export const OrgSecretSummarySchema = z.object({
57
+ id: z.string().uuid(),
58
+ orgId: z.string().uuid().nullable(),
59
+ usageClass: UsageClassSchema,
60
+ secretName: z.string().min(1).max(128),
61
+ maskedPrefix: z.string().min(1).max(64),
62
+ version: z.number().int().positive(),
63
+ enabled: z.boolean(),
64
+ lastUsedAt: z.string().datetime().nullable(),
65
+ usageCount: z.string(),
66
+ rotatedAt: z.string().datetime().nullable(),
67
+ createdAt: z.string().datetime(),
68
+ });
69
+ export type OrgSecretSummary = z.infer<typeof OrgSecretSummarySchema>;
70
+
71
+ /**
72
+ * Request to create a new org secret. Server-side handlers must wrap
73
+ * `plaintext` in Secret<T> immediately on receipt.
74
+ */
75
+ export const CreateSecretRequestSchema = z.object({
76
+ orgId: z.string().uuid().nullable(),
77
+ usageClass: UsageClassSchema,
78
+ secretName: z.string().min(1).max(128),
79
+ plaintext: SecretValueStringSchema,
80
+ reason: z.string().max(512).optional(),
81
+ });
82
+ export type CreateSecretRequest = z.infer<typeof CreateSecretRequestSchema>;
83
+
84
+ /**
85
+ * Request to rotate an existing secret to a new plaintext value.
86
+ */
87
+ export const RotateSecretRequestSchema = z.object({
88
+ newPlaintext: SecretValueStringSchema,
89
+ reason: z.string().max(512).optional(),
90
+ });
91
+ export type RotateSecretRequest = z.infer<typeof RotateSecretRequestSchema>;
92
+
93
+ /**
94
+ * Request to disable an existing secret. A non-empty `reason` is required so
95
+ * the audit trail always captures why a credential was taken out of service.
96
+ */
97
+ export const DisableSecretRequestSchema = z.object({
98
+ reason: z.string().min(1).max(512),
99
+ });
100
+ export type DisableSecretRequest = z.infer<typeof DisableSecretRequestSchema>;