@creatornader/agent-bridge 0.4.0 → 0.5.1

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 (77) hide show
  1. package/CHANGELOG.md +85 -1
  2. package/README.md +76 -7
  3. package/ROADMAP.md +29 -0
  4. package/SECURITY.md +30 -0
  5. package/SKILL.md +5 -1
  6. package/dist/archive.d.ts +2 -2
  7. package/dist/{bridge-service-YTjGr91A.d.ts → bridge-service-CNBKdYXh.d.ts} +2 -1
  8. package/dist/{bridge-store-Boaj-ZbO.d.ts → bridge-store-ByJ6CaJk.d.ts} +1 -0
  9. package/dist/bridge.d.ts +15 -8
  10. package/dist/bridge.js +10 -8
  11. package/dist/{chunk-PDIHDBP3.js → chunk-7VJI2MXI.js} +116 -26
  12. package/dist/chunk-7VJI2MXI.js.map +1 -0
  13. package/dist/{chunk-4VB44KJU.js → chunk-AWE3DFZV.js} +3 -2
  14. package/dist/chunk-AWE3DFZV.js.map +1 -0
  15. package/dist/{chunk-IHZFI7TH.js → chunk-E4OWHGUE.js} +5 -2
  16. package/dist/chunk-E4OWHGUE.js.map +1 -0
  17. package/dist/{chunk-SYGONYMM.js → chunk-HUHG7XTB.js} +6 -5
  18. package/dist/chunk-HUHG7XTB.js.map +1 -0
  19. package/dist/{chunk-DQOZJJZ2.js → chunk-IVG4XWWS.js} +5 -5
  20. package/dist/{chunk-DQOZJJZ2.js.map → chunk-IVG4XWWS.js.map} +1 -1
  21. package/dist/{chunk-3YHVUPU2.js → chunk-P635FAN4.js} +4 -4
  22. package/dist/chunk-P635FAN4.js.map +1 -0
  23. package/dist/{chunk-6BTJE6D4.js → chunk-QNXHDOJ5.js} +56 -23
  24. package/dist/chunk-QNXHDOJ5.js.map +1 -0
  25. package/dist/{chunk-MCKKVNCE.js → chunk-QPC6JHA3.js} +5 -5
  26. package/dist/{chunk-SV3SVBYS.js → chunk-SN7PIVDF.js} +2 -2
  27. package/dist/{chunk-2DFNOLMO.js → chunk-XDNT6ZNZ.js} +9 -6
  28. package/dist/chunk-XDNT6ZNZ.js.map +1 -0
  29. package/dist/{chunk-LAHNQZDN.js → chunk-Z6JP6MYD.js} +2 -2
  30. package/dist/cli.js +9 -9
  31. package/dist/cli.js.map +1 -1
  32. package/dist/client-runtime.d.ts +3 -3
  33. package/dist/client-runtime.js +6 -6
  34. package/dist/contracts/generate.js +1 -1
  35. package/dist/dr.js +3 -3
  36. package/dist/{gateway-BQHpV-MZ.d.ts → gateway-CW-61lvs.d.ts} +2 -2
  37. package/dist/gateway-main.js +71 -7
  38. package/dist/gateway-main.js.map +1 -1
  39. package/dist/gateway.d.ts +3 -3
  40. package/dist/gateway.js +3 -3
  41. package/dist/index.js +7 -7
  42. package/dist/{postgres-bridge-store-WASumj26.d.ts → postgres-bridge-store-C9KG9Z69.d.ts} +1 -1
  43. package/dist/postgres-production-preflight.d.ts +32 -0
  44. package/dist/postgres-production-preflight.js +249 -0
  45. package/dist/postgres-production-preflight.js.map +1 -0
  46. package/dist/server.js +7 -7
  47. package/dist/{sqlite-edge-store-Bc15DvpX.d.ts → sqlite-edge-store-CdMIOrho.d.ts} +1 -1
  48. package/dist/sqlite.d.ts +3 -3
  49. package/dist/sqlite.js +2 -2
  50. package/docs/architecture-v2.md +36 -5
  51. package/docs/deployment.md +157 -0
  52. package/llms.txt +2 -1
  53. package/openapi/agent-bridge-v2.openapi.json +5 -1
  54. package/package.json +5 -1
  55. package/schemas/agent-bridge-v2.capabilities.json +2 -1
  56. package/schemas/agent-bridge-v2.mcp.json +5 -1
  57. package/schemas/agent-bridge-v2.schema.json +4 -0
  58. package/sql/migrations/007_runtime_role.sql +8 -4
  59. package/sql/migrations/013_row_isolation.sql +71 -8
  60. package/sql/migrations/014_owner_control_plane.sql +124 -31
  61. package/sql/migrations/015_portable_archives.sql +143 -41
  62. package/sql/migrations/016_native_dr_fence.sql +102 -35
  63. package/sql/migrations/018_endpoint_migration_challenges.sql +36 -10
  64. package/sql/migrations/019_endpoint_migration_same_successor.sql +34 -10
  65. package/sql/migrations/020_managed_authority_compat.sql +698 -0
  66. package/sql/migrations/021_native_backup_reader.sql +421 -0
  67. package/sql/setup.sql +1 -3
  68. package/dist/chunk-2DFNOLMO.js.map +0 -1
  69. package/dist/chunk-3YHVUPU2.js.map +0 -1
  70. package/dist/chunk-4VB44KJU.js.map +0 -1
  71. package/dist/chunk-6BTJE6D4.js.map +0 -1
  72. package/dist/chunk-IHZFI7TH.js.map +0 -1
  73. package/dist/chunk-PDIHDBP3.js.map +0 -1
  74. package/dist/chunk-SYGONYMM.js.map +0 -1
  75. /package/dist/{chunk-MCKKVNCE.js.map → chunk-QPC6JHA3.js.map} +0 -0
  76. /package/dist/{chunk-SV3SVBYS.js.map → chunk-SN7PIVDF.js.map} +0 -0
  77. /package/dist/{chunk-LAHNQZDN.js.map → chunk-Z6JP6MYD.js.map} +0 -0
@@ -26,11 +26,73 @@ begin
26
26
  role_name
27
27
  );
28
28
  end if;
29
- execute format(
30
- 'alter role %I nologin nosuperuser nocreatedb nocreaterole noreplication nobypassrls',
31
- role_name
32
- );
33
- execute format('grant %I to %I with admin option',role_name,current_user);
29
+ if exists (
30
+ select 1 from pg_catalog.pg_roles where rolname=role_name and (
31
+ rolcanlogin or not rolinherit or rolsuper or rolcreatedb or rolcreaterole
32
+ or rolreplication or rolbypassrls or rolconnlimit<>-1
33
+ )
34
+ ) then
35
+ raise exception 'Agent Bridge archive role has unsafe attributes';
36
+ end if;
37
+ if current_setting('server_version_num')::integer>=160000 then
38
+ if not exists (
39
+ select 1 from pg_catalog.pg_auth_members membership
40
+ join pg_catalog.pg_roles granted on granted.oid=membership.roleid
41
+ join pg_catalog.pg_roles member on member.oid=membership.member
42
+ where granted.rolname=role_name and member.rolname=current_user
43
+ and membership.admin_option
44
+ ) then
45
+ execute format(
46
+ 'grant %I to %I with admin true,inherit true,set true',role_name,current_user
47
+ );
48
+ elsif not exists (
49
+ select 1 from pg_catalog.pg_auth_members membership
50
+ join pg_catalog.pg_roles granted on granted.oid=membership.roleid
51
+ join pg_catalog.pg_roles member on member.oid=membership.member
52
+ where granted.rolname=role_name and member.rolname=current_user
53
+ and coalesce((to_jsonb(membership)->>'inherit_option')::boolean,true)
54
+ and coalesce((to_jsonb(membership)->>'set_option')::boolean,true)
55
+ ) then
56
+ execute format('grant %I to %I with inherit true,set true',role_name,current_user);
57
+ end if;
58
+ elsif not exists (
59
+ select 1 from pg_catalog.pg_auth_members membership
60
+ join pg_catalog.pg_roles granted on granted.oid=membership.roleid
61
+ join pg_catalog.pg_roles member on member.oid=membership.member
62
+ where granted.rolname=role_name and member.rolname=current_user
63
+ and membership.admin_option
64
+ ) then
65
+ execute format('grant %I to %I with admin option',role_name,current_user);
66
+ end if;
67
+ if not exists (
68
+ select 1 from pg_catalog.pg_auth_members membership
69
+ join pg_catalog.pg_roles granted on granted.oid=membership.roleid
70
+ join pg_catalog.pg_roles member on member.oid=membership.member
71
+ where granted.rolname=role_name and member.rolname=current_user
72
+ and membership.admin_option
73
+ ) or not exists (
74
+ select 1 from pg_catalog.pg_auth_members membership
75
+ join pg_catalog.pg_roles granted on granted.oid=membership.roleid
76
+ join pg_catalog.pg_roles member on member.oid=membership.member
77
+ where granted.rolname=role_name and member.rolname=current_user
78
+ and coalesce((to_jsonb(membership)->>'inherit_option')::boolean,true)
79
+ and coalesce((to_jsonb(membership)->>'set_option')::boolean,true)
80
+ ) or exists (
81
+ select 1 from pg_catalog.pg_auth_members membership
82
+ join pg_catalog.pg_roles granted on granted.oid=membership.roleid
83
+ join pg_catalog.pg_roles member on member.oid=membership.member
84
+ where granted.rolname=role_name and member.rolname=current_user
85
+ and not (
86
+ (membership.grantor=10 and membership.admin_option
87
+ and coalesce((to_jsonb(membership)->>'inherit_option')::boolean,true)
88
+ =coalesce((to_jsonb(membership)->>'set_option')::boolean,true))
89
+ or (membership.grantor=member.oid
90
+ and coalesce((to_jsonb(membership)->>'inherit_option')::boolean,true)
91
+ and coalesce((to_jsonb(membership)->>'set_option')::boolean,true))
92
+ )
93
+ ) then
94
+ raise exception 'Agent Bridge archive role has unsafe owner authority';
95
+ end if;
34
96
  end
35
97
  $roles$;
36
98
 
@@ -215,19 +277,28 @@ begin
215
277
  select event.action from agent_bridge.archive_membership_events event
216
278
  where event.member_role=session_user order by event.sequence desc limit 1
217
279
  ), direct_membership as (
218
- select membership.admin_option,
219
- coalesce((to_jsonb(membership)->>'inherit_option')::boolean,true) inherit_option,
220
- coalesce((to_jsonb(membership)->>'set_option')::boolean,true) set_option,
221
- grantor.rolname grantor_role
280
+ select bool_or(membership.admin_option) admin_option,
281
+ bool_or(coalesce((to_jsonb(membership)->>'inherit_option')::boolean,true)) inherit_option,
282
+ bool_or(coalesce((to_jsonb(membership)->>'set_option')::boolean,true)) set_option,
283
+ bool_and(case when member.rolname=schema_owner then
284
+ (membership.grantor=10 and membership.admin_option
285
+ and coalesce((to_jsonb(membership)->>'inherit_option')::boolean,true)
286
+ =coalesce((to_jsonb(membership)->>'set_option')::boolean,true))
287
+ or (membership.grantor=member.oid
288
+ and coalesce((to_jsonb(membership)->>'inherit_option')::boolean,true)
289
+ and coalesce((to_jsonb(membership)->>'set_option')::boolean,true))
290
+ else membership.grantor=(select oid from pg_catalog.pg_roles where rolname=schema_owner)
291
+ and not membership.admin_option
292
+ and coalesce((to_jsonb(membership)->>'inherit_option')::boolean,true)
293
+ and coalesce((to_jsonb(membership)->>'set_option')::boolean,true) end) grants_valid
222
294
  from pg_catalog.pg_auth_members membership
223
295
  join pg_catalog.pg_roles granted on granted.oid=membership.roleid
224
296
  join pg_catalog.pg_roles member on member.oid=membership.member
225
- join pg_catalog.pg_roles grantor on grantor.oid=membership.grantor
226
297
  where member.rolname=session_user and granted.rolname=archive_role
227
298
  )
228
299
  select coalesce(bool_or(
229
300
  membership.inherit_option and membership.set_option
230
- and membership.grantor_role=schema_owner and (
301
+ and membership.grants_valid and (
231
302
  (session_user=schema_owner and membership.admin_option)
232
303
  or (latest.action='register' and not membership.admin_option)
233
304
  )
@@ -1396,15 +1467,15 @@ returns text language sql stable set search_path = '' set timezone = 'UTC' as $$
1396
1467
  from pg_catalog.pg_roles role where role.rolname=(select archive_role from names)
1397
1468
  union all
1398
1469
  select 'owner_membership',granted.rolname||'->'||member.rolname,
1399
- grantor.rolname||':'||membership.admin_option::text||':'||
1400
- coalesce(to_jsonb(membership)->>'inherit_option','')||':'||
1401
- coalesce(to_jsonb(membership)->>'set_option','')
1470
+ bool_or(membership.admin_option)::text||':'||
1471
+ bool_or(coalesce((to_jsonb(membership)->>'inherit_option')::boolean,true))::text||':'||
1472
+ bool_or(coalesce((to_jsonb(membership)->>'set_option')::boolean,true))::text
1402
1473
  from pg_catalog.pg_auth_members membership
1403
1474
  join pg_catalog.pg_roles granted on granted.oid=membership.roleid
1404
1475
  join pg_catalog.pg_roles member on member.oid=membership.member
1405
- join pg_catalog.pg_roles grantor on grantor.oid=membership.grantor
1406
1476
  where granted.rolname=(select archive_role from names)
1407
1477
  and member.oid=(select schema_owner from names)
1478
+ group by granted.rolname,member.rolname
1408
1479
  union all
1409
1480
  select 'schema','agent_bridge',pg_catalog.pg_get_userbyid(namespace.nspowner)
1410
1481
  from pg_catalog.pg_namespace namespace where namespace.oid=(select schema_oid from names)
@@ -1542,19 +1613,35 @@ returns boolean language sql stable security definer set search_path = '' as $$
1542
1613
  ), active_registry as (
1543
1614
  select member_role from latest_registry where action='register'
1544
1615
  ), expected_memberships as (
1545
- select names.archive_role granted_role,names.schema_owner member_role,true admin_option from names
1546
- union all select names.archive_role,registry.member_role,false from active_registry registry cross join names
1547
- ), actual_memberships as (
1616
+ select names.archive_role granted_role,names.schema_owner member_role,
1617
+ true admin_option,true inherit_option,true set_option from names
1618
+ union all select names.archive_role,registry.member_role,false,true,true
1619
+ from active_registry registry cross join names
1620
+ ), raw_memberships as (
1548
1621
  select granted.rolname::name granted_role,member.rolname::name member_role,
1549
1622
  membership.admin_option,
1550
1623
  coalesce((to_jsonb(membership)->>'inherit_option')::boolean,true) inherit_option,
1551
1624
  coalesce((to_jsonb(membership)->>'set_option')::boolean,true) set_option,
1552
- grantor.rolname::name grantor_role
1625
+ membership.grantor,member.oid member_oid
1553
1626
  from pg_catalog.pg_auth_members membership
1554
1627
  join pg_catalog.pg_roles granted on granted.oid=membership.roleid
1555
1628
  join pg_catalog.pg_roles member on member.oid=membership.member
1556
- join pg_catalog.pg_roles grantor on grantor.oid=membership.grantor
1557
1629
  where granted.rolname=(select archive_role from names)
1630
+ ), actual_memberships as (
1631
+ select membership.granted_role,membership.member_role,
1632
+ bool_or(membership.admin_option) admin_option,
1633
+ bool_or(membership.inherit_option) inherit_option,
1634
+ bool_or(membership.set_option) set_option,
1635
+ bool_and(case when membership.member_role=names.schema_owner then
1636
+ (membership.grantor=10 and membership.admin_option
1637
+ and membership.inherit_option=membership.set_option)
1638
+ or (membership.grantor=membership.member_oid
1639
+ and membership.inherit_option and membership.set_option)
1640
+ else membership.grantor=(select oid from pg_catalog.pg_roles where rolname=names.schema_owner)
1641
+ and not membership.admin_option
1642
+ and membership.inherit_option and membership.set_option end) grants_valid
1643
+ from raw_memberships membership cross join names
1644
+ group by membership.granted_role,membership.member_role
1558
1645
  )
1559
1646
  select current_setting('server_version_num')::integer/10000=any(array[15,16,17,18])
1560
1647
  and exists(select 1 from pg_catalog.pg_roles role,names where role.rolname=names.archive_role
@@ -1565,15 +1652,13 @@ returns boolean language sql stable security definer set search_path = '' as $$
1565
1652
  ) from agent_bridge.portable_archive_attestations attestation
1566
1653
  where attestation.name='portable-archive-v1')
1567
1654
  and not exists(
1568
- (select granted_role,member_role,admin_option from actual_memberships
1569
- except select granted_role,member_role,admin_option from expected_memberships)
1655
+ (select granted_role,member_role,admin_option,inherit_option,set_option from actual_memberships
1656
+ except select granted_role,member_role,admin_option,inherit_option,set_option from expected_memberships)
1570
1657
  union all
1571
- (select granted_role,member_role,admin_option from expected_memberships
1572
- except select granted_role,member_role,admin_option from actual_memberships)
1658
+ (select granted_role,member_role,admin_option,inherit_option,set_option from expected_memberships
1659
+ except select granted_role,member_role,admin_option,inherit_option,set_option from actual_memberships)
1573
1660
  )
1574
- and not exists(select 1 from actual_memberships membership,names
1575
- where not membership.inherit_option or not membership.set_option
1576
- or membership.grantor_role<>names.schema_owner)
1661
+ and not exists(select 1 from actual_memberships membership where not membership.grants_valid)
1577
1662
  and not exists(select 1 from active_registry registry
1578
1663
  left join pg_catalog.pg_roles role on role.rolname=registry.member_role
1579
1664
  where role.oid is null or not role.rolcanlogin or role.rolsuper or role.rolcreaterole
@@ -1706,27 +1791,42 @@ returns boolean language sql stable security definer set search_path = '' as $$
1706
1791
  ), active_registry as (
1707
1792
  select member_role,control_role from latest_registry where action='register'
1708
1793
  ), expected_memberships as (
1709
- select names.owner_role granted_role,names.schema_owner member_role,true admin_option
1794
+ select names.owner_role granted_role,names.schema_owner member_role,
1795
+ true admin_option,true inherit_option,true set_option
1710
1796
  from names
1711
- union all select names.operator_role,names.schema_owner,true from names
1712
- union all select names.auditor_role,names.schema_owner,true from names
1797
+ union all select names.operator_role,names.schema_owner,true,true,true from names
1798
+ union all select names.auditor_role,names.schema_owner,true,true,true from names
1713
1799
  union all
1714
1800
  select case registry.control_role when 'operator' then names.operator_role
1715
- else names.auditor_role end,registry.member_role,false
1801
+ else names.auditor_role end,registry.member_role,false,true,true
1716
1802
  from active_registry registry cross join names
1717
- ), actual_memberships as (
1803
+ ), raw_memberships as (
1718
1804
  select granted.rolname::name granted_role,member.rolname::name member_role,
1719
1805
  membership.admin_option,
1720
1806
  coalesce((to_jsonb(membership)->>'inherit_option')::boolean,true) inherit_option,
1721
1807
  coalesce((to_jsonb(membership)->>'set_option')::boolean,true) set_option,
1722
- grantor.rolname::name grantor_role
1808
+ membership.grantor,member.oid member_oid
1723
1809
  from pg_catalog.pg_auth_members membership
1724
1810
  join pg_catalog.pg_roles granted on granted.oid=membership.roleid
1725
1811
  join pg_catalog.pg_roles member on member.oid=membership.member
1726
- join pg_catalog.pg_roles grantor on grantor.oid=membership.grantor
1727
1812
  where granted.rolname in (
1728
1813
  (select owner_role from names),(select operator_role from names),(select auditor_role from names)
1729
1814
  )
1815
+ ), actual_memberships as (
1816
+ select membership.granted_role,membership.member_role,
1817
+ bool_or(membership.admin_option) admin_option,
1818
+ bool_or(membership.inherit_option) inherit_option,
1819
+ bool_or(membership.set_option) set_option,
1820
+ bool_and(case when membership.member_role=names.schema_owner then
1821
+ (membership.grantor=10 and membership.admin_option
1822
+ and membership.inherit_option=membership.set_option)
1823
+ or (membership.grantor=membership.member_oid
1824
+ and membership.inherit_option and membership.set_option)
1825
+ else membership.grantor=(select oid from pg_catalog.pg_roles where rolname=names.schema_owner)
1826
+ and not membership.admin_option
1827
+ and membership.inherit_option and membership.set_option end) grants_valid
1828
+ from raw_memberships membership cross join names
1829
+ group by membership.granted_role,membership.member_role
1730
1830
  ), authority_closure as (
1731
1831
  select control_role.granted_role,candidate.rolname::name member_role
1732
1832
  from names
@@ -1745,16 +1845,14 @@ returns boolean language sql stable security definer set search_path = '' as $$
1745
1845
  ) from agent_bridge.owner_control_attestations attestation
1746
1846
  where attestation.name='owner-control-v2')
1747
1847
  and not exists (
1748
- (select granted_role,member_role,admin_option from actual_memberships
1749
- except select granted_role,member_role,admin_option from expected_memberships)
1848
+ (select granted_role,member_role,admin_option,inherit_option,set_option from actual_memberships
1849
+ except select granted_role,member_role,admin_option,inherit_option,set_option from expected_memberships)
1750
1850
  union all
1751
- (select granted_role,member_role,admin_option from expected_memberships
1752
- except select granted_role,member_role,admin_option from actual_memberships)
1851
+ (select granted_role,member_role,admin_option,inherit_option,set_option from expected_memberships
1852
+ except select granted_role,member_role,admin_option,inherit_option,set_option from actual_memberships)
1753
1853
  )
1754
1854
  and not exists (
1755
- select 1 from actual_memberships membership,names
1756
- where not membership.inherit_option or not membership.set_option
1757
- or membership.grantor_role<>names.schema_owner
1855
+ select 1 from actual_memberships membership where not membership.grants_valid
1758
1856
  )
1759
1857
  and not exists (
1760
1858
  select 1 from active_registry registry
@@ -1792,8 +1890,12 @@ returns boolean language sql stable security definer set search_path = '' as $$
1792
1890
  )
1793
1891
  $$;
1794
1892
 
1893
+ select set_config(
1894
+ 'role','agent_bridge_control_owner_'||substr(md5(current_database()),1,16),false
1895
+ );
1795
1896
  insert into agent_bridge.owner_control_attestations(name,catalog_definition)
1796
1897
  values('owner-control-v2',agent_bridge.owner_control_catalog_definition());
1898
+ reset role;
1797
1899
 
1798
1900
  insert into agent_bridge.portable_archive_attestations(name,catalog_definition)
1799
1901
  values('portable-archive-v1',agent_bridge.portable_archive_catalog_definition());
@@ -146,23 +146,36 @@ begin
146
146
  where event.member_role=session_user and event.control_role in ('operator','auditor')
147
147
  order by event.control_role,event.sequence desc
148
148
  ), direct_membership as (
149
- select granted.rolname control_role,membership.admin_option,
150
- coalesce((to_jsonb(membership)->>'inherit_option')::boolean,true) inherit_option,
151
- coalesce((to_jsonb(membership)->>'set_option')::boolean,true) set_option
149
+ select granted.rolname control_role,
150
+ bool_or(membership.admin_option) admin_option,
151
+ bool_or(coalesce((to_jsonb(membership)->>'inherit_option')::boolean,true)) inherit_option,
152
+ bool_or(coalesce((to_jsonb(membership)->>'set_option')::boolean,true)) set_option,
153
+ bool_and(case when member.rolname=schema_owner then
154
+ (membership.grantor=10 and membership.admin_option
155
+ and coalesce((to_jsonb(membership)->>'inherit_option')::boolean,true)
156
+ =coalesce((to_jsonb(membership)->>'set_option')::boolean,true))
157
+ or (membership.grantor=member.oid
158
+ and coalesce((to_jsonb(membership)->>'inherit_option')::boolean,true)
159
+ and coalesce((to_jsonb(membership)->>'set_option')::boolean,true))
160
+ else membership.grantor=(select oid from pg_catalog.pg_roles where rolname=schema_owner)
161
+ and not membership.admin_option
162
+ and coalesce((to_jsonb(membership)->>'inherit_option')::boolean,true)
163
+ and coalesce((to_jsonb(membership)->>'set_option')::boolean,true) end) grants_valid
152
164
  from pg_catalog.pg_auth_members membership
153
165
  join pg_catalog.pg_roles granted on granted.oid=membership.roleid
154
166
  join pg_catalog.pg_roles member on member.oid=membership.member
155
167
  where member.rolname=session_user and granted.rolname in (operator_role,auditor_role)
168
+ group by granted.rolname
156
169
  )
157
170
  select
158
171
  coalesce(bool_or(membership.control_role=operator_role
159
- and membership.inherit_option and membership.set_option and (
172
+ and membership.inherit_option and membership.set_option and membership.grants_valid and (
160
173
  (session_user=schema_owner and membership.admin_option)
161
174
  or (latest.control_role='operator' and latest.action='register'
162
175
  and not membership.admin_option)
163
176
  )),false),
164
177
  coalesce(bool_or(membership.control_role=auditor_role
165
- and membership.inherit_option and membership.set_option and (
178
+ and membership.inherit_option and membership.set_option and membership.grants_valid and (
166
179
  (session_user=schema_owner and membership.admin_option)
167
180
  or (latest.control_role='auditor' and latest.action='register'
168
181
  and not membership.admin_option)
@@ -379,16 +392,27 @@ begin
379
392
  select event.action from agent_bridge.archive_membership_events event
380
393
  where event.member_role=session_user order by event.sequence desc limit 1
381
394
  ), direct_membership as (
382
- select membership.admin_option,
383
- coalesce((to_jsonb(membership)->>'inherit_option')::boolean,true) inherit_option,
384
- coalesce((to_jsonb(membership)->>'set_option')::boolean,true) set_option
395
+ select bool_or(membership.admin_option) admin_option,
396
+ bool_or(coalesce((to_jsonb(membership)->>'inherit_option')::boolean,true)) inherit_option,
397
+ bool_or(coalesce((to_jsonb(membership)->>'set_option')::boolean,true)) set_option,
398
+ bool_and(case when member.rolname=schema_owner then
399
+ (membership.grantor=10 and membership.admin_option
400
+ and coalesce((to_jsonb(membership)->>'inherit_option')::boolean,true)
401
+ =coalesce((to_jsonb(membership)->>'set_option')::boolean,true))
402
+ or (membership.grantor=member.oid
403
+ and coalesce((to_jsonb(membership)->>'inherit_option')::boolean,true)
404
+ and coalesce((to_jsonb(membership)->>'set_option')::boolean,true))
405
+ else membership.grantor=(select oid from pg_catalog.pg_roles where rolname=schema_owner)
406
+ and not membership.admin_option
407
+ and coalesce((to_jsonb(membership)->>'inherit_option')::boolean,true)
408
+ and coalesce((to_jsonb(membership)->>'set_option')::boolean,true) end) grants_valid
385
409
  from pg_catalog.pg_auth_members membership
386
410
  join pg_catalog.pg_roles granted on granted.oid=membership.roleid
387
411
  join pg_catalog.pg_roles member on member.oid=membership.member
388
412
  where member.rolname=session_user and granted.rolname=archive_role
389
413
  )
390
414
  select coalesce(bool_or(
391
- membership.inherit_option and membership.set_option and (
415
+ membership.inherit_option and membership.set_option and membership.grants_valid and (
392
416
  (session_user=schema_owner and membership.admin_option)
393
417
  or (latest.action='register' and not membership.admin_option)
394
418
  )
@@ -596,14 +620,15 @@ returns text language sql stable set search_path = '' as $$
596
620
  )
597
621
  union all
598
622
  select 'membership',granted.rolname||'->'||member.rolname,
599
- membership.admin_option::text||':'||
600
- coalesce(to_jsonb(membership)->>'inherit_option','true')||':'||
601
- coalesce(to_jsonb(membership)->>'set_option','true')
623
+ bool_or(membership.admin_option)::text||':'||
624
+ bool_or(coalesce((to_jsonb(membership)->>'inherit_option')::boolean,true))::text||':'||
625
+ bool_or(coalesce((to_jsonb(membership)->>'set_option')::boolean,true))::text
602
626
  from pg_catalog.pg_auth_members membership
603
627
  join pg_catalog.pg_roles granted on granted.oid=membership.roleid
604
628
  join pg_catalog.pg_roles member on member.oid=membership.member
605
629
  where member.rolname in (select role_name from control_roles)
606
630
  or granted.rolname=(select owner_role from names)
631
+ group by granted.rolname,member.rolname
607
632
  union all
608
633
  select 'relation_acl',relation.oid::regclass::text,
609
634
  pg_catalog.pg_get_userbyid(privilege.grantor)||':'||
@@ -692,14 +717,15 @@ returns text language sql stable set search_path = '' as $$
692
717
  )
693
718
  union all
694
719
  select 'owner_membership',granted.rolname||'->'||member.rolname,
695
- membership.admin_option::text||':'||
696
- coalesce(to_jsonb(membership)->>'inherit_option','true')||':'||
697
- coalesce(to_jsonb(membership)->>'set_option','true')
720
+ bool_or(membership.admin_option)::text||':'||
721
+ bool_or(coalesce((to_jsonb(membership)->>'inherit_option')::boolean,true))::text||':'||
722
+ bool_or(coalesce((to_jsonb(membership)->>'set_option')::boolean,true))::text
698
723
  from pg_catalog.pg_auth_members membership
699
724
  join pg_catalog.pg_roles granted on granted.oid=membership.roleid
700
725
  join pg_catalog.pg_roles member on member.oid=membership.member
701
726
  where granted.rolname=(select archive_role from names)
702
727
  and member.oid=(select schema_owner from names)
728
+ group by granted.rolname,member.rolname
703
729
  union all
704
730
  select 'relation_acl',relation.oid::regclass::text,
705
731
  pg_catalog.pg_get_userbyid(privilege.grantor)||':'||
@@ -764,10 +790,12 @@ do $ownership$
764
790
  declare
765
791
  owner_role text := 'agent_bridge_control_owner_'||substr(md5(current_database()),1,16);
766
792
  begin
793
+ execute format('grant create on schema agent_bridge to %I',owner_role);
767
794
  execute format(
768
795
  'alter function agent_bridge.owner_control_attestation_definition() owner to %I',
769
796
  owner_role
770
797
  );
798
+ execute format('revoke create on schema agent_bridge from %I',owner_role);
771
799
  end
772
800
  $ownership$;
773
801
 
@@ -783,17 +811,35 @@ returns boolean language sql stable security definer set search_path = '' as $$
783
811
  ), active_registry as (
784
812
  select member_role from latest_registry where action='register'
785
813
  ), expected_memberships as (
786
- select names.archive_role granted_role,names.schema_owner member_role,true admin_option from names
787
- union all select names.archive_role,registry.member_role,false from active_registry registry cross join names
788
- ), actual_memberships as (
814
+ select names.archive_role granted_role,names.schema_owner member_role,
815
+ true admin_option,true inherit_option,true set_option from names
816
+ union all select names.archive_role,registry.member_role,false,true,true
817
+ from active_registry registry cross join names
818
+ ), raw_memberships as (
789
819
  select granted.rolname::name granted_role,member.rolname::name member_role,
790
820
  membership.admin_option,
791
821
  coalesce((to_jsonb(membership)->>'inherit_option')::boolean,true) inherit_option,
792
- coalesce((to_jsonb(membership)->>'set_option')::boolean,true) set_option
822
+ coalesce((to_jsonb(membership)->>'set_option')::boolean,true) set_option,
823
+ membership.grantor,member.oid member_oid
793
824
  from pg_catalog.pg_auth_members membership
794
825
  join pg_catalog.pg_roles granted on granted.oid=membership.roleid
795
826
  join pg_catalog.pg_roles member on member.oid=membership.member
796
827
  where granted.rolname=(select archive_role from names)
828
+ ), actual_memberships as (
829
+ select membership.granted_role,membership.member_role,
830
+ bool_or(membership.admin_option) admin_option,
831
+ bool_or(membership.inherit_option) inherit_option,
832
+ bool_or(membership.set_option) set_option,
833
+ bool_and(case when membership.member_role=names.schema_owner then
834
+ (membership.grantor=10 and membership.admin_option
835
+ and membership.inherit_option=membership.set_option)
836
+ or (membership.grantor=membership.member_oid
837
+ and membership.inherit_option and membership.set_option)
838
+ else membership.grantor=(select oid from pg_catalog.pg_roles where rolname=names.schema_owner)
839
+ and not membership.admin_option
840
+ and membership.inherit_option and membership.set_option end) grants_valid
841
+ from raw_memberships membership cross join names
842
+ group by membership.granted_role,membership.member_role
797
843
  )
798
844
  select current_setting('server_version_num')::integer/10000=any(array[15,16,17,18])
799
845
  and exists(select 1 from pg_catalog.pg_roles role,names where role.rolname=names.archive_role
@@ -804,14 +850,14 @@ returns boolean language sql stable security definer set search_path = '' as $$
804
850
  ) from agent_bridge.portable_archive_attestations attestation
805
851
  where attestation.name='portable-archive-v3')
806
852
  and not exists(
807
- (select granted_role,member_role,admin_option from actual_memberships
808
- except select granted_role,member_role,admin_option from expected_memberships)
853
+ (select granted_role,member_role,admin_option,inherit_option,set_option from actual_memberships
854
+ except select granted_role,member_role,admin_option,inherit_option,set_option from expected_memberships)
809
855
  union all
810
- (select granted_role,member_role,admin_option from expected_memberships
811
- except select granted_role,member_role,admin_option from actual_memberships)
856
+ (select granted_role,member_role,admin_option,inherit_option,set_option from expected_memberships
857
+ except select granted_role,member_role,admin_option,inherit_option,set_option from actual_memberships)
812
858
  )
813
859
  and not exists(select 1 from actual_memberships membership
814
- where not membership.inherit_option or not membership.set_option)
860
+ where not membership.grants_valid)
815
861
  and not exists(select 1 from active_registry registry
816
862
  left join pg_catalog.pg_roles role on role.rolname=registry.member_role
817
863
  where role.oid is null or not role.rolcanlogin or role.rolsuper or role.rolcreaterole
@@ -901,24 +947,41 @@ returns boolean language sql stable security definer set search_path = '' as $$
901
947
  ), active_registry as (
902
948
  select member_role,control_role from latest_registry where action='register'
903
949
  ), expected_memberships as (
904
- select names.owner_role granted_role,names.schema_owner member_role,true admin_option from names
905
- union all select names.operator_role,names.schema_owner,true from names
906
- union all select names.auditor_role,names.schema_owner,true from names
950
+ select names.owner_role granted_role,names.schema_owner member_role,
951
+ true admin_option,true inherit_option,true set_option from names
952
+ union all select names.operator_role,names.schema_owner,true,true,true from names
953
+ union all select names.auditor_role,names.schema_owner,true,true,true from names
907
954
  union all
908
955
  select case registry.control_role when 'operator' then names.operator_role
909
- else names.auditor_role end,registry.member_role,false
956
+ else names.auditor_role end,registry.member_role,false,true,true
910
957
  from active_registry registry cross join names
911
- ), actual_memberships as (
958
+ ), raw_memberships as (
912
959
  select granted.rolname::name granted_role,member.rolname::name member_role,
913
960
  membership.admin_option,
914
961
  coalesce((to_jsonb(membership)->>'inherit_option')::boolean,true) inherit_option,
915
- coalesce((to_jsonb(membership)->>'set_option')::boolean,true) set_option
962
+ coalesce((to_jsonb(membership)->>'set_option')::boolean,true) set_option,
963
+ membership.grantor,member.oid member_oid
916
964
  from pg_catalog.pg_auth_members membership
917
965
  join pg_catalog.pg_roles granted on granted.oid=membership.roleid
918
966
  join pg_catalog.pg_roles member on member.oid=membership.member
919
967
  where granted.rolname in (
920
968
  (select owner_role from names),(select operator_role from names),(select auditor_role from names)
921
969
  )
970
+ ), actual_memberships as (
971
+ select membership.granted_role,membership.member_role,
972
+ bool_or(membership.admin_option) admin_option,
973
+ bool_or(membership.inherit_option) inherit_option,
974
+ bool_or(membership.set_option) set_option,
975
+ bool_and(case when membership.member_role=names.schema_owner then
976
+ (membership.grantor=10 and membership.admin_option
977
+ and membership.inherit_option=membership.set_option)
978
+ or (membership.grantor=membership.member_oid
979
+ and membership.inherit_option and membership.set_option)
980
+ else membership.grantor=(select oid from pg_catalog.pg_roles where rolname=names.schema_owner)
981
+ and not membership.admin_option
982
+ and membership.inherit_option and membership.set_option end) grants_valid
983
+ from raw_memberships membership cross join names
984
+ group by membership.granted_role,membership.member_role
922
985
  ), authority_closure as (
923
986
  select control_role.granted_role,candidate.rolname::name member_role
924
987
  from names
@@ -937,14 +1000,14 @@ returns boolean language sql stable security definer set search_path = '' as $$
937
1000
  ) from agent_bridge.owner_control_attestations attestation
938
1001
  where attestation.name='owner-control-v4')
939
1002
  and not exists (
940
- (select granted_role,member_role,admin_option from actual_memberships
941
- except select granted_role,member_role,admin_option from expected_memberships)
1003
+ (select granted_role,member_role,admin_option,inherit_option,set_option from actual_memberships
1004
+ except select granted_role,member_role,admin_option,inherit_option,set_option from expected_memberships)
942
1005
  union all
943
- (select granted_role,member_role,admin_option from expected_memberships
944
- except select granted_role,member_role,admin_option from actual_memberships)
1006
+ (select granted_role,member_role,admin_option,inherit_option,set_option from expected_memberships
1007
+ except select granted_role,member_role,admin_option,inherit_option,set_option from actual_memberships)
945
1008
  )
946
1009
  and not exists (select 1 from actual_memberships membership
947
- where not membership.inherit_option or not membership.set_option)
1010
+ where not membership.grants_valid)
948
1011
  and not exists (
949
1012
  select 1 from active_registry registry
950
1013
  left join pg_catalog.pg_roles role_record on role_record.rolname=registry.member_role
@@ -981,8 +1044,12 @@ returns boolean language sql stable security definer set search_path = '' as $$
981
1044
  )
982
1045
  $$;
983
1046
 
1047
+ select set_config(
1048
+ 'role','agent_bridge_control_owner_'||substr(md5(current_database()),1,16),false
1049
+ );
984
1050
  insert into agent_bridge.owner_control_attestations(name,catalog_definition)
985
1051
  values('owner-control-v4',agent_bridge.owner_control_attestation_definition());
1052
+ reset role;
986
1053
 
987
1054
  insert into agent_bridge.portable_archive_attestations(name,catalog_definition)
988
1055
  values('portable-archive-v3',agent_bridge.portable_archive_attestation_definition());
@@ -899,19 +899,37 @@ returns boolean language sql stable security definer set search_path = '' as $$
899
899
  ), active_registry as (
900
900
  select member_role,control_role from latest_registry where action='register'
901
901
  ), expected_memberships as (
902
- select names.owner_role granted_role,names.schema_owner member_role,true admin_option from names
903
- union all select names.operator_role,names.schema_owner,true from names
904
- union all select names.auditor_role,names.schema_owner,true from names
902
+ select names.owner_role granted_role,names.schema_owner member_role,
903
+ true admin_option,true inherit_option,true set_option from names
904
+ union all select names.operator_role,names.schema_owner,true,true,true from names
905
+ union all select names.auditor_role,names.schema_owner,true,true,true from names
905
906
  union all select case registry.control_role when 'operator' then names.operator_role else names.auditor_role end,
906
- registry.member_role,false from active_registry registry cross join names
907
- ), actual_memberships as (
908
- select granted.rolname::name granted_role,member.rolname::name member_role,membership.admin_option,
907
+ registry.member_role,false,true,true from active_registry registry cross join names
908
+ ), raw_memberships as (
909
+ select granted.rolname::name granted_role,member.rolname::name member_role,
910
+ membership.admin_option,
909
911
  coalesce((to_jsonb(membership)->>'inherit_option')::boolean,true) inherit_option,
910
- coalesce((to_jsonb(membership)->>'set_option')::boolean,true) set_option
912
+ coalesce((to_jsonb(membership)->>'set_option')::boolean,true) set_option,
913
+ membership.grantor,member.oid member_oid
911
914
  from pg_catalog.pg_auth_members membership
912
915
  join pg_catalog.pg_roles granted on granted.oid=membership.roleid
913
916
  join pg_catalog.pg_roles member on member.oid=membership.member
914
917
  where granted.rolname in ((select owner_role from names),(select operator_role from names),(select auditor_role from names))
918
+ ), actual_memberships as (
919
+ select membership.granted_role,membership.member_role,
920
+ bool_or(membership.admin_option) admin_option,
921
+ bool_or(membership.inherit_option) inherit_option,
922
+ bool_or(membership.set_option) set_option,
923
+ bool_and(case when membership.member_role=names.schema_owner then
924
+ (membership.grantor=10 and membership.admin_option
925
+ and membership.inherit_option=membership.set_option)
926
+ or (membership.grantor=membership.member_oid
927
+ and membership.inherit_option and membership.set_option)
928
+ else membership.grantor=(select oid from pg_catalog.pg_roles where rolname=names.schema_owner)
929
+ and not membership.admin_option
930
+ and membership.inherit_option and membership.set_option end) grants_valid
931
+ from raw_memberships membership cross join names
932
+ group by membership.granted_role,membership.member_role
915
933
  ), authority_closure as (
916
934
  select control_role.granted_role,candidate.rolname::name member_role
917
935
  from names cross join lateral(values(names.owner_role),(names.operator_role),(names.auditor_role)) control_role(granted_role)
@@ -924,10 +942,12 @@ returns boolean language sql stable security definer set search_path = '' as $$
924
942
  and(select count(*)=1 and bool_and(catalog_definition=agent_bridge.owner_control_attestation_definition())
925
943
  from agent_bridge.owner_control_attestations where name='owner-control-v5')
926
944
  and not exists(
927
- (select granted_role,member_role,admin_option from actual_memberships except select granted_role,member_role,admin_option from expected_memberships)
928
- union all(select granted_role,member_role,admin_option from expected_memberships except select granted_role,member_role,admin_option from actual_memberships)
945
+ (select granted_role,member_role,admin_option,inherit_option,set_option from actual_memberships
946
+ except select granted_role,member_role,admin_option,inherit_option,set_option from expected_memberships)
947
+ union all(select granted_role,member_role,admin_option,inherit_option,set_option from expected_memberships
948
+ except select granted_role,member_role,admin_option,inherit_option,set_option from actual_memberships)
929
949
  )
930
- and not exists(select 1 from actual_memberships where not inherit_option or not set_option)
950
+ and not exists(select 1 from actual_memberships where not grants_valid)
931
951
  and not exists(select 1 from active_registry registry left join pg_catalog.pg_roles role_record on role_record.rolname=registry.member_role
932
952
  where role_record.oid is null or not role_record.rolcanlogin or role_record.rolsuper or role_record.rolcreaterole
933
953
  or role_record.rolcreatedb or role_record.rolreplication or role_record.rolbypassrls)
@@ -967,7 +987,9 @@ declare
967
987
  control_owner text := 'agent_bridge_control_owner_'||substr(md5(current_database()),1,16);
968
988
  role_name text;
969
989
  begin
990
+ execute format('grant create on schema agent_bridge to %I',control_owner);
970
991
  execute format('alter function agent_bridge.owner_control_plane_ready() owner to %I',control_owner);
992
+ execute format('revoke create on schema agent_bridge from %I',control_owner);
971
993
  foreach role_name in array array[
972
994
  'guard_endpoint_migration_challenge()',
973
995
  'reject_endpoint_migration_challenge_truncate()',
@@ -1003,8 +1025,12 @@ $ownership_and_grants$;
1003
1025
 
1004
1026
  insert into agent_bridge.endpoint_migration_challenge_attestations(name,catalog_definition)
1005
1027
  values('endpoint-migration-v1',agent_bridge.endpoint_migration_challenge_catalog_definition());
1028
+ select set_config(
1029
+ 'role','agent_bridge_control_owner_'||substr(md5(current_database()),1,16),false
1030
+ );
1006
1031
  insert into agent_bridge.owner_control_attestations(name,catalog_definition)
1007
1032
  values('owner-control-v5',agent_bridge.owner_control_attestation_definition());
1033
+ reset role;
1008
1034
 
1009
1035
  do $final_readiness$
1010
1036
  begin