@consiliency/agent-board-schema 1.3.0 → 1.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/bin/agent-board-schema.js +0 -0
- package/fixtures/already-applied.json +112 -0
- package/migrations/20260717000100_agent_board_board_role.sql +180 -0
- package/migrations/20260717000200_agent_board_thread_acl.sql +149 -0
- package/migrations/20260717000300_agent_board_agent_lineage.sql +54 -0
- package/migrations/20260717000400_agent_board_delegation_policies.sql +175 -0
- package/migrations/20260718000100_agent_board_send_authz_config.sql +172 -0
- package/migrations/20260718000200_agent_board_send_role_gate.sql +804 -0
- package/migrations/20260718000300_agent_board_fleet_policy_default_deny.sql +192 -0
- package/migrations/20260718000400_agent_board_grant_ceiling_wiring.sql +58 -0
- package/migrations/20260718000500_agent_board_fleet_agent_session_class.sql +24 -0
- package/migrations/20260718000600_agent_board_mint_fleet_agent_session.sql +172 -0
- package/migrations/20260718000700_agent_board_nonfleet_session_reaper.sql +35 -0
- package/migrations/20260718000800_agent_board_regrant_scoped_send.sql +24 -0
- package/migrations/20260718000900_agent_board_agents_status_revoked.sql +24 -0
- package/migrations/20260718001000_agent_board_delegation_enforcement.sql +296 -0
- package/migrations/20260718001100_agent_board_revoke_agent_subtree.sql +238 -0
- package/migrations/20260718001200_agent_board_resigning_refresh.sql +129 -0
- package/migrations/20260718001300_agent_board_identity_providers.sql +70 -0
- package/migrations/20260718001400_agent_board_enrollment_federation_audit.sql +50 -0
- package/migrations/20260718001500_agent_board_enroll_federated_identity.sql +220 -0
- package/migrations/20260719000100_agent_board_signing_challenge_pending_cap.sql +124 -0
- package/migrations/20260719000200_agent_board_signing_challenge_reaper.sql +34 -0
- package/migrations/20260719000300_agent_board_enroll_rate_cap.sql +72 -0
- package/migrations/20260719001000_agent_board_identity_providers_portal_contract.sql +38 -0
- package/migrations/20260719001100_agent_board_enroll_federated_identity_pop.sql +267 -0
- package/migrations/20260719001200_agent_board_enroll_federated_identity_raw_fingerprint.sql +296 -0
- package/migrations/20260719001300_agent_board_enroll_rate_events_reaper_rls.sql +62 -0
- package/migrations/20260723000100_agent_board_roomown_owner_seed.sql +167 -0
- package/migrations/20260723000200_agent_board_roomown_grant_role_live.sql +72 -0
- package/package.json +9 -9
- package/schema-manifest.json +256 -4
- package/src/tooling.test.mjs +46 -1
- package/tests/agent_board_agent_lineage.test.sql +73 -0
- package/tests/agent_board_agents_status_revoked.test.sql +60 -0
- package/tests/agent_board_auth_rpcs.test.sql +17 -16
- package/tests/agent_board_board_role.test.sql +129 -0
- package/tests/agent_board_bundle_endpoint_compat.test.sql +18 -6
- package/tests/agent_board_canary_signed_fleet_enforcement.test.sql +8 -8
- package/tests/agent_board_delegation_enforcement.test.sql +175 -0
- package/tests/agent_board_delegation_policies.test.sql +120 -0
- package/tests/agent_board_enroll_federated_identity.test.sql +217 -0
- package/tests/agent_board_enroll_pop_binding.test.sql +131 -0
- package/tests/agent_board_enroll_rate_cap.test.sql +53 -0
- package/tests/agent_board_enrollment_audit_content.test.sql +139 -0
- package/tests/agent_board_fleet_agent_session_class.test.sql +64 -0
- package/tests/agent_board_fleet_policy_default_deny.test.sql +149 -0
- package/tests/agent_board_fleet_registry.test.sql +2 -2
- package/tests/agent_board_identity_providers.test.sql +104 -0
- package/tests/agent_board_inbox_rpcs.test.sql +10 -10
- package/tests/agent_board_mint_fleet_agent_session.test.sql +290 -0
- package/tests/agent_board_nonfleet_session_reaper.test.sql +61 -0
- package/tests/agent_board_portal_offline_invariant.test.sql +134 -0
- package/tests/agent_board_resigning_refresh.test.sql +73 -0
- package/tests/agent_board_revoke_agent_subtree.test.sql +188 -0
- package/tests/agent_board_roomown.test.sql +233 -0
- package/tests/agent_board_schema_version.test.sql +2 -2
- package/tests/agent_board_schema_version_rpc.test.sql +1 -1
- package/tests/agent_board_scoped_send_regrant.test.sql +142 -0
- package/tests/agent_board_send_authz_config.test.sql +84 -0
- package/tests/agent_board_send_authz_matrix.test.sql +162 -0
- package/tests/agent_board_send_role_gate.test.sql +181 -0
- package/tests/agent_board_signing_challenge_pending_cap.test.sql +87 -0
- package/tests/agent_board_signing_challenge_reaper.test.sql +74 -0
- package/tests/agent_board_thread_acl.test.sql +129 -0
- package/tests/agent_board_v2_invariants.test.sql +5 -5
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
-- MBAUTHZ SL-2 (Lane B) pgTAP: threads.access_mode, thread_memberships (+RLS),
|
|
2
|
+
-- and the redefined _current_agent_can_access_thread.
|
|
3
|
+
--
|
|
4
|
+
-- The suite runs as the postgres db role (superuser, so it can call the
|
|
5
|
+
-- grant-revoked access helper), and simulates callers by toggling
|
|
6
|
+
-- request.jwt.claim.role / request.jwt.claim.sub: role='authenticated' makes
|
|
7
|
+
-- _is_service_role() false so the real access logic runs; role='service_role'
|
|
8
|
+
-- exercises the short-circuit.
|
|
9
|
+
create extension if not exists pgtap with schema extensions;
|
|
10
|
+
set search_path = extensions, public, agent_board;
|
|
11
|
+
|
|
12
|
+
begin;
|
|
13
|
+
|
|
14
|
+
select plan(14);
|
|
15
|
+
|
|
16
|
+
create temp table _thread_acl_fixture (
|
|
17
|
+
thread_inherit uuid,
|
|
18
|
+
thread_restricted uuid,
|
|
19
|
+
creator_user uuid,
|
|
20
|
+
member_user uuid,
|
|
21
|
+
stranger_user uuid,
|
|
22
|
+
expired_user uuid,
|
|
23
|
+
revoked_user uuid
|
|
24
|
+
) on commit drop;
|
|
25
|
+
|
|
26
|
+
do $$
|
|
27
|
+
declare
|
|
28
|
+
v_suffix text := replace(substr(gen_random_uuid()::text, 1, 8), '-', '');
|
|
29
|
+
v_creator_user uuid;
|
|
30
|
+
v_member_user uuid;
|
|
31
|
+
v_stranger_user uuid;
|
|
32
|
+
v_expired_user uuid;
|
|
33
|
+
v_revoked_user uuid;
|
|
34
|
+
v_creator uuid := gen_random_uuid();
|
|
35
|
+
v_member uuid := gen_random_uuid();
|
|
36
|
+
v_stranger uuid := gen_random_uuid();
|
|
37
|
+
v_expired uuid := gen_random_uuid();
|
|
38
|
+
v_revoked uuid := gen_random_uuid();
|
|
39
|
+
v_thread_inherit uuid := gen_random_uuid();
|
|
40
|
+
v_thread_restricted uuid := gen_random_uuid();
|
|
41
|
+
begin
|
|
42
|
+
v_creator_user := public.ensure_github_user('acl-creator-' || v_suffix, 'acl-creator-' || v_suffix || '@example.test', 'acl-creator-' || v_suffix, 'ACL Creator');
|
|
43
|
+
v_member_user := public.ensure_github_user('acl-member-' || v_suffix, 'acl-member-' || v_suffix || '@example.test', 'acl-member-' || v_suffix, 'ACL Member');
|
|
44
|
+
v_stranger_user := public.ensure_github_user('acl-stranger-' || v_suffix, 'acl-stranger-' || v_suffix || '@example.test', 'acl-stranger-' || v_suffix, 'ACL Stranger');
|
|
45
|
+
v_expired_user := public.ensure_github_user('acl-expired-' || v_suffix, 'acl-expired-' || v_suffix || '@example.test', 'acl-expired-' || v_suffix, 'ACL Expired');
|
|
46
|
+
v_revoked_user := public.ensure_github_user('acl-revoked-' || v_suffix, 'acl-revoked-' || v_suffix || '@example.test', 'acl-revoked-' || v_suffix, 'ACL Revoked');
|
|
47
|
+
|
|
48
|
+
insert into agent_board.agents(id, agent_type, handle, display_name, status, auth_user_id, owner_user_id)
|
|
49
|
+
values
|
|
50
|
+
(v_creator, 'agent', 'acl-creator-' || v_suffix, 'ACL Creator', 'active', v_creator_user, v_creator_user),
|
|
51
|
+
(v_member, 'agent', 'acl-member-' || v_suffix, 'ACL Member', 'active', v_member_user, v_member_user),
|
|
52
|
+
(v_stranger, 'agent', 'acl-stranger-' || v_suffix, 'ACL Stranger', 'active', v_stranger_user, v_stranger_user),
|
|
53
|
+
(v_expired, 'agent', 'acl-expired-' || v_suffix, 'ACL Expired', 'active', v_expired_user, v_expired_user),
|
|
54
|
+
(v_revoked, 'agent', 'acl-revoked-' || v_suffix, 'ACL Revoked', 'active', v_revoked_user, v_revoked_user);
|
|
55
|
+
|
|
56
|
+
-- inherit thread (default access_mode) and a restricted thread.
|
|
57
|
+
insert into agent_board.threads(id, thread_type, created_by_agent_id, subject)
|
|
58
|
+
values (v_thread_inherit, 'coordination', v_creator, 'ACL inherit thread');
|
|
59
|
+
insert into agent_board.threads(id, thread_type, created_by_agent_id, subject, access_mode)
|
|
60
|
+
values (v_thread_restricted, 'coordination', v_creator, 'ACL restricted thread', 'restricted');
|
|
61
|
+
|
|
62
|
+
-- ACL on the restricted thread: active member, expired member, revoked member.
|
|
63
|
+
insert into agent_board.thread_memberships(thread_id, agent_id, role, granted_by_agent_id, expires_at, revoked_at)
|
|
64
|
+
values
|
|
65
|
+
(v_thread_restricted, v_member, 'member', v_creator, null, null),
|
|
66
|
+
(v_thread_restricted, v_expired, 'member', v_creator, now() - interval '1 hour', null),
|
|
67
|
+
(v_thread_restricted, v_revoked, 'member', v_creator, null, now() - interval '1 hour');
|
|
68
|
+
|
|
69
|
+
insert into _thread_acl_fixture values
|
|
70
|
+
(v_thread_inherit, v_thread_restricted, v_creator_user, v_member_user, v_stranger_user, v_expired_user, v_revoked_user);
|
|
71
|
+
end
|
|
72
|
+
$$;
|
|
73
|
+
|
|
74
|
+
-- Structure -----------------------------------------------------------------
|
|
75
|
+
select has_column('agent_board', 'threads', 'access_mode', 'threads has access_mode');
|
|
76
|
+
select col_type_is('agent_board', 'threads', 'access_mode', 'text', 'access_mode is text');
|
|
77
|
+
select col_has_check('agent_board', 'threads', 'access_mode', 'access_mode is check-constrained');
|
|
78
|
+
select is(
|
|
79
|
+
(select access_mode from agent_board.threads t join _thread_acl_fixture f on t.id = f.thread_inherit),
|
|
80
|
+
'inherit', 'access_mode defaults to inherit');
|
|
81
|
+
select has_table('agent_board', 'thread_memberships', 'thread_memberships table exists');
|
|
82
|
+
select has_column('agent_board', 'thread_memberships', 'thread_id', 'thread_memberships has thread_id');
|
|
83
|
+
select is(
|
|
84
|
+
(select relrowsecurity from pg_class where oid = 'agent_board.thread_memberships'::regclass),
|
|
85
|
+
true, 'RLS is enabled on thread_memberships');
|
|
86
|
+
|
|
87
|
+
-- inherit mode: historical OR preserved -------------------------------------
|
|
88
|
+
select set_config('request.jwt.claim.role', 'authenticated', true);
|
|
89
|
+
select set_config('request.jwt.claim.sub', (select creator_user from _thread_acl_fixture)::text, true);
|
|
90
|
+
select is(
|
|
91
|
+
agent_board._current_agent_can_access_thread((select thread_inherit from _thread_acl_fixture)),
|
|
92
|
+
true, 'inherit: creator retains access');
|
|
93
|
+
|
|
94
|
+
select set_config('request.jwt.claim.sub', (select stranger_user from _thread_acl_fixture)::text, true);
|
|
95
|
+
select is(
|
|
96
|
+
agent_board._current_agent_can_access_thread((select thread_inherit from _thread_acl_fixture)),
|
|
97
|
+
false, 'inherit: unrelated agent has no access');
|
|
98
|
+
|
|
99
|
+
-- service_role short-circuit: restricted thread, no membership -> allowed ----
|
|
100
|
+
select set_config('request.jwt.claim.role', 'service_role', true);
|
|
101
|
+
select is(
|
|
102
|
+
agent_board._current_agent_can_access_thread((select thread_restricted from _thread_acl_fixture)),
|
|
103
|
+
true, 'service_role bypasses restricted access');
|
|
104
|
+
|
|
105
|
+
-- restricted mode -----------------------------------------------------------
|
|
106
|
+
select set_config('request.jwt.claim.role', 'authenticated', true);
|
|
107
|
+
select set_config('request.jwt.claim.sub', (select creator_user from _thread_acl_fixture)::text, true);
|
|
108
|
+
select is(
|
|
109
|
+
agent_board._current_agent_can_access_thread((select thread_restricted from _thread_acl_fixture)),
|
|
110
|
+
false, 'restricted: creator without an ACL grant is denied');
|
|
111
|
+
|
|
112
|
+
select set_config('request.jwt.claim.sub', (select member_user from _thread_acl_fixture)::text, true);
|
|
113
|
+
select is(
|
|
114
|
+
agent_board._current_agent_can_access_thread((select thread_restricted from _thread_acl_fixture)),
|
|
115
|
+
true, 'restricted: active ACL member is granted');
|
|
116
|
+
|
|
117
|
+
select set_config('request.jwt.claim.sub', (select expired_user from _thread_acl_fixture)::text, true);
|
|
118
|
+
select is(
|
|
119
|
+
agent_board._current_agent_can_access_thread((select thread_restricted from _thread_acl_fixture)),
|
|
120
|
+
false, 'restricted: expired ACL member is denied');
|
|
121
|
+
|
|
122
|
+
select set_config('request.jwt.claim.sub', (select revoked_user from _thread_acl_fixture)::text, true);
|
|
123
|
+
select is(
|
|
124
|
+
agent_board._current_agent_can_access_thread((select thread_restricted from _thread_acl_fixture)),
|
|
125
|
+
false, 'restricted: revoked ACL member is denied');
|
|
126
|
+
|
|
127
|
+
select finish();
|
|
128
|
+
|
|
129
|
+
rollback;
|
|
@@ -323,8 +323,8 @@ select *
|
|
|
323
323
|
|
|
324
324
|
select is(
|
|
325
325
|
(select delivered_recipient_count from v2_board_delivery),
|
|
326
|
-
|
|
327
|
-
'post_board_message only reaches active joined or subscribed board members'
|
|
326
|
+
3,
|
|
327
|
+
'post_board_message only reaches active joined or subscribed board members (incl. the seeded owner-creator)'
|
|
328
328
|
);
|
|
329
329
|
|
|
330
330
|
select is(
|
|
@@ -369,13 +369,13 @@ select *
|
|
|
369
369
|
|
|
370
370
|
select is(
|
|
371
371
|
(select delivered_recipient_count from v2_tasking_delivery),
|
|
372
|
-
|
|
373
|
-
'tasking counts explicit and board fan-out attempts before duplicate collapse'
|
|
372
|
+
4,
|
|
373
|
+
'tasking counts explicit and board fan-out attempts before duplicate collapse (incl. the seeded owner-creator)'
|
|
374
374
|
);
|
|
375
375
|
|
|
376
376
|
select is(
|
|
377
377
|
(select count(*)::integer from agent_board.delivery_recipients where source_task_id = (select task_id from v2_tasking_delivery)),
|
|
378
|
-
|
|
378
|
+
3,
|
|
379
379
|
'tasking suppresses duplicate durable recipient rows across explicit and board fan-out'
|
|
380
380
|
);
|
|
381
381
|
|