@consiliency/agent-board-schema 1.3.0 → 1.4.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 (62) hide show
  1. package/bin/agent-board-schema.js +0 -0
  2. package/fixtures/already-applied.json +104 -0
  3. package/migrations/20260717000100_agent_board_board_role.sql +180 -0
  4. package/migrations/20260717000200_agent_board_thread_acl.sql +149 -0
  5. package/migrations/20260717000300_agent_board_agent_lineage.sql +54 -0
  6. package/migrations/20260717000400_agent_board_delegation_policies.sql +175 -0
  7. package/migrations/20260718000100_agent_board_send_authz_config.sql +172 -0
  8. package/migrations/20260718000200_agent_board_send_role_gate.sql +804 -0
  9. package/migrations/20260718000300_agent_board_fleet_policy_default_deny.sql +192 -0
  10. package/migrations/20260718000400_agent_board_grant_ceiling_wiring.sql +58 -0
  11. package/migrations/20260718000500_agent_board_fleet_agent_session_class.sql +24 -0
  12. package/migrations/20260718000600_agent_board_mint_fleet_agent_session.sql +172 -0
  13. package/migrations/20260718000700_agent_board_nonfleet_session_reaper.sql +35 -0
  14. package/migrations/20260718000800_agent_board_regrant_scoped_send.sql +24 -0
  15. package/migrations/20260718000900_agent_board_agents_status_revoked.sql +24 -0
  16. package/migrations/20260718001000_agent_board_delegation_enforcement.sql +296 -0
  17. package/migrations/20260718001100_agent_board_revoke_agent_subtree.sql +238 -0
  18. package/migrations/20260718001200_agent_board_resigning_refresh.sql +129 -0
  19. package/migrations/20260718001300_agent_board_identity_providers.sql +70 -0
  20. package/migrations/20260718001400_agent_board_enrollment_federation_audit.sql +50 -0
  21. package/migrations/20260718001500_agent_board_enroll_federated_identity.sql +220 -0
  22. package/migrations/20260719000100_agent_board_signing_challenge_pending_cap.sql +124 -0
  23. package/migrations/20260719000200_agent_board_signing_challenge_reaper.sql +34 -0
  24. package/migrations/20260719000300_agent_board_enroll_rate_cap.sql +72 -0
  25. package/migrations/20260719001000_agent_board_identity_providers_portal_contract.sql +38 -0
  26. package/migrations/20260719001100_agent_board_enroll_federated_identity_pop.sql +267 -0
  27. package/migrations/20260719001200_agent_board_enroll_federated_identity_raw_fingerprint.sql +296 -0
  28. package/migrations/20260719001300_agent_board_enroll_rate_events_reaper_rls.sql +62 -0
  29. package/package.json +9 -9
  30. package/schema-manifest.json +238 -4
  31. package/src/tooling.test.mjs +42 -1
  32. package/tests/agent_board_agent_lineage.test.sql +73 -0
  33. package/tests/agent_board_agents_status_revoked.test.sql +60 -0
  34. package/tests/agent_board_auth_rpcs.test.sql +17 -16
  35. package/tests/agent_board_board_role.test.sql +129 -0
  36. package/tests/agent_board_bundle_endpoint_compat.test.sql +18 -6
  37. package/tests/agent_board_canary_signed_fleet_enforcement.test.sql +8 -8
  38. package/tests/agent_board_delegation_enforcement.test.sql +175 -0
  39. package/tests/agent_board_delegation_policies.test.sql +119 -0
  40. package/tests/agent_board_enroll_federated_identity.test.sql +217 -0
  41. package/tests/agent_board_enroll_pop_binding.test.sql +131 -0
  42. package/tests/agent_board_enroll_rate_cap.test.sql +53 -0
  43. package/tests/agent_board_enrollment_audit_content.test.sql +134 -0
  44. package/tests/agent_board_fleet_agent_session_class.test.sql +64 -0
  45. package/tests/agent_board_fleet_policy_default_deny.test.sql +149 -0
  46. package/tests/agent_board_fleet_registry.test.sql +2 -2
  47. package/tests/agent_board_identity_providers.test.sql +104 -0
  48. package/tests/agent_board_inbox_rpcs.test.sql +6 -6
  49. package/tests/agent_board_mint_fleet_agent_session.test.sql +290 -0
  50. package/tests/agent_board_nonfleet_session_reaper.test.sql +61 -0
  51. package/tests/agent_board_portal_offline_invariant.test.sql +130 -0
  52. package/tests/agent_board_resigning_refresh.test.sql +73 -0
  53. package/tests/agent_board_revoke_agent_subtree.test.sql +188 -0
  54. package/tests/agent_board_schema_version.test.sql +2 -2
  55. package/tests/agent_board_schema_version_rpc.test.sql +1 -1
  56. package/tests/agent_board_scoped_send_regrant.test.sql +138 -0
  57. package/tests/agent_board_send_authz_config.test.sql +84 -0
  58. package/tests/agent_board_send_authz_matrix.test.sql +159 -0
  59. package/tests/agent_board_send_role_gate.test.sql +177 -0
  60. package/tests/agent_board_signing_challenge_pending_cap.test.sql +87 -0
  61. package/tests/agent_board_signing_challenge_reaper.test.sql +74 -0
  62. package/tests/agent_board_thread_acl.test.sql +129 -0
@@ -0,0 +1,172 @@
1
+ -- MBSENDAUTHZ SL-0 (preamble): shared send-authz enforcement config + telemetry.
2
+ --
3
+ -- Additive, dormant. Creates the single-writer shared objects that SL-1/SL-2/SL-3
4
+ -- consume:
5
+ -- * agent_board.fleet_send_enforcement_flags — per-sender-fleet-scope mode flag
6
+ -- (absent row => fail_open_preserved, i.e. current behavior unchanged).
7
+ -- * agent_board.nonfleet_sender_allowlist — legitimate non-fleet system flows,
8
+ -- consulted only under deny mode. Structure is code; population is operational.
9
+ -- * agent_board.send_authz_telemetry (+ recorder) — per-call authz telemetry with
10
+ -- the frozen EF-vs-host origin discriminator that MBDELEG's host-bypass drain
11
+ -- gate reads.
12
+ -- * agent_board._resolve_send_fleet_scope / _send_fleet_scope_mode — the fleet
13
+ -- scope resolver + flag-mode lookup.
14
+ --
15
+ -- No send-path behavior changes here: these objects are only wired into the send
16
+ -- path by SL-1 (bypass telemetry) and SL-2 (non-fleet default-deny). schema_version
17
+ -- is intentionally NOT bumped (phase is dormant/additive).
18
+
19
+ -- 1. fleet_send_enforcement_flags (IF-0-MBSENDAUTHZ-2) -----------------------
20
+ -- Board-native (agent_board.*), deliberately NOT public.app_settings. Absent row
21
+ -- for a scope => fail_open_preserved (preserves current behavior for that scope).
22
+ create table if not exists agent_board.fleet_send_enforcement_flags (
23
+ scope_key text primary key,
24
+ mode text not null default 'fail_open_preserved'
25
+ check (mode in ('fail_open_preserved', 'observe', 'deny')),
26
+ updated_at timestamptz not null default now()
27
+ );
28
+
29
+ comment on table agent_board.fleet_send_enforcement_flags is
30
+ 'Per-sender-fleet-scope send enforcement mode. Absent row => fail_open_preserved (current behavior). observe => allow + record would_be_deny; deny => deny non-allowlisted non-fleet senders. Operator-managed (service_role).';
31
+
32
+ alter table agent_board.fleet_send_enforcement_flags enable row level security;
33
+ grant select, insert, update, delete on agent_board.fleet_send_enforcement_flags to service_role;
34
+
35
+ -- 2. nonfleet_sender_allowlist (IF-0-MBSENDAUTHZ-6) --------------------------
36
+ -- Enumerates legitimate non-fleet system flows; consulted only under deny mode.
37
+ -- Structure is code; population is operational (derived from the observe pass).
38
+ create table if not exists agent_board.nonfleet_sender_allowlist (
39
+ agent_id uuid primary key references agent_board.agents(id) on delete cascade,
40
+ reason text not null,
41
+ created_at timestamptz not null default now()
42
+ );
43
+
44
+ comment on table agent_board.nonfleet_sender_allowlist is
45
+ 'Tight allowlist of legitimate non-fleet system senders. Consulted only under deny mode: a non-fleet sender is admitted iff it has a row here. Population is operational (derived from the observe pass).';
46
+
47
+ alter table agent_board.nonfleet_sender_allowlist enable row level security;
48
+ grant select, insert, update, delete on agent_board.nonfleet_sender_allowlist to service_role;
49
+
50
+ -- 3. send_authz_telemetry (IF-0-MBSENDAUTHZ-5) ------------------------------
51
+ -- Per-call authz telemetry. origin is the frozen EF-vs-host discriminator that
52
+ -- MBDELEG's "zero host-originated service_role" drain gate reads.
53
+ create table if not exists agent_board.send_authz_telemetry (
54
+ id uuid primary key default gen_random_uuid(),
55
+ kind text not null check (kind in ('service_role_bypass', 'would_be_deny')),
56
+ origin text not null check (origin in ('ef', 'host', 'unknown')),
57
+ actor_agent_id uuid,
58
+ board_id uuid,
59
+ operation text,
60
+ scope_key text,
61
+ denial_class text,
62
+ metadata jsonb not null default '{}'::jsonb,
63
+ recorded_at timestamptz not null default now()
64
+ );
65
+
66
+ comment on table agent_board.send_authz_telemetry is
67
+ 'Per-call send authorization telemetry. kind=service_role_bypass (a service_role guarded-bypass send) or would_be_deny (a non-fleet send that deny mode would have blocked). origin (ef|host|unknown) is the frozen host-vs-EF discriminator MBDELEG drains against.';
68
+
69
+ create index if not exists idx_agent_board_send_authz_telemetry_kind_origin
70
+ on agent_board.send_authz_telemetry(kind, origin, recorded_at desc);
71
+
72
+ alter table agent_board.send_authz_telemetry enable row level security;
73
+ grant select, insert on agent_board.send_authz_telemetry to service_role;
74
+
75
+ create or replace function agent_board._record_send_authz_telemetry(
76
+ p_kind text,
77
+ p_origin text,
78
+ p_actor_agent_id uuid,
79
+ p_board_id uuid,
80
+ p_operation text,
81
+ p_scope_key text,
82
+ p_denial_class text,
83
+ p_metadata jsonb default '{}'::jsonb
84
+ )
85
+ returns uuid
86
+ language plpgsql
87
+ security definer
88
+ set search_path = agent_board, public
89
+ as $$
90
+ declare
91
+ v_id uuid;
92
+ begin
93
+ if not agent_board._is_service_role() then
94
+ raise exception 'send authz telemetry recording requires service role' using errcode = '42501';
95
+ end if;
96
+ insert into agent_board.send_authz_telemetry(
97
+ kind, origin, actor_agent_id, board_id, operation, scope_key, denial_class, metadata
98
+ ) values (
99
+ p_kind,
100
+ case when p_origin in ('ef', 'host') then p_origin else 'unknown' end,
101
+ p_actor_agent_id,
102
+ p_board_id,
103
+ p_operation,
104
+ p_scope_key,
105
+ p_denial_class,
106
+ coalesce(p_metadata, '{}'::jsonb)
107
+ ) returning id into v_id;
108
+ return v_id;
109
+ end;
110
+ $$;
111
+
112
+ comment on function agent_board._record_send_authz_telemetry(text, text, uuid, uuid, text, text, text, jsonb) is
113
+ 'Service_role-only recorder for send_authz_telemetry. Normalizes origin to ef|host|unknown. Called internally by the send RPCs (bypass) and the fleet policy (would_be_deny).';
114
+
115
+ revoke all on function agent_board._record_send_authz_telemetry(text, text, uuid, uuid, text, text, text, jsonb) from public, anon, authenticated;
116
+ grant execute on function agent_board._record_send_authz_telemetry(text, text, uuid, uuid, text, text, text, jsonb) to service_role;
117
+
118
+ -- 4. fleet scope resolver + flag-mode lookup (IF-0-MBSENDAUTHZ-3) ------------
119
+ -- Trust-domain-derived scope where the sender is fleet-resolvable (mirrors the
120
+ -- active-machine resolution in evaluate_signed_write_fleet_policy), else the single
121
+ -- catch-all 'nonfleet' bucket (the v_machine_id is null population).
122
+ create or replace function agent_board._resolve_send_fleet_scope(
123
+ p_actor uuid
124
+ )
125
+ returns text
126
+ language sql
127
+ stable
128
+ security definer
129
+ set search_path = ''
130
+ as $$
131
+ select coalesce(
132
+ (select 'fleet:' || ftd.slug
133
+ from agent_board.fleet_machine_agents fma
134
+ join agent_board.fleet_machines fm on fm.id = fma.machine_id
135
+ join agent_board.fleet_trust_domains ftd on ftd.id = fm.trust_domain_id
136
+ where fma.agent_id = p_actor
137
+ and fma.lifecycle_state = 'active'
138
+ and fm.lifecycle_state = 'active'
139
+ order by fma.updated_at desc
140
+ limit 1),
141
+ 'nonfleet'
142
+ )
143
+ $$;
144
+
145
+ comment on function agent_board._resolve_send_fleet_scope(uuid) is
146
+ 'Resolves a sender to its trust-domain-derived fleet scope key, or the catch-all ''nonfleet'' bucket when the sender has no active fleet machine.';
147
+
148
+ revoke all on function agent_board._resolve_send_fleet_scope(uuid) from public, anon, authenticated;
149
+ grant execute on function agent_board._resolve_send_fleet_scope(uuid) to service_role;
150
+
151
+ create or replace function agent_board._send_fleet_scope_mode(
152
+ p_scope_key text
153
+ )
154
+ returns text
155
+ language sql
156
+ stable
157
+ security definer
158
+ set search_path = ''
159
+ as $$
160
+ select coalesce(
161
+ (select mode
162
+ from agent_board.fleet_send_enforcement_flags
163
+ where scope_key = p_scope_key),
164
+ 'fail_open_preserved'
165
+ )
166
+ $$;
167
+
168
+ comment on function agent_board._send_fleet_scope_mode(text) is
169
+ 'Resolves the enforcement mode for a sender-fleet-scope key, defaulting to fail_open_preserved when no flag row exists.';
170
+
171
+ revoke all on function agent_board._send_fleet_scope_mode(text) from public, anon, authenticated;
172
+ grant execute on function agent_board._send_fleet_scope_mode(text) to service_role;