mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
feat: add boundary_log rbac resource (#24810)
RFC: [Bridge ↔ Boundaries Correlation RFC](https://www.notion.so/coderhq/Gateway-and-Firewall-Correlation-RFC-31ad579be592803aa8b3d48348ccdde9) Register a dedicated `boundary_log` RBAC resource type with `create`, `read`, and `delete` actions, replacing the placeholder `rbac.ResourceAuditLog` and `rbac.ResourceSystem` references previously used in the dbauthz layer. Create is granted at user-level so workspace agents can only write logs owned by their workspace owner, preventing cross-workspace log fabrication. Delete is restricted to `DBPurge` only; no human role (including owner) can delete boundary logs. | Subject | Create (own) | Create (other) | Read (all) | Delete | |---|---|---|---|---| | Workspace agent | yes | no | no | no | | Owner (site admin) | yes (via member) | no | yes | no | | Auditor | no | no | yes | no | | DBPurge | no | no | no | yes | ### Changes - **RBAC policy & resource definition**: add `boundary_log` to `policy.go` and generate `ResourceBoundaryLog` object, scope constants, and codersdk/TypeScript types. - **dbauthz authorization**: replace all `ResourceAuditLog`/`ResourceSystem` placeholders with `ResourceBoundaryLog`. `InsertBoundaryLog` and `InsertBoundarySession` derive the workspace owner from the agent and authorize with `.WithOwner()` for user-scoped create. - **Role assignments:** - **Owner (site):** read only. Excluded from `allPermsExcept` wildcard; create is inherited from member at user-level. - **Member (user-level):** create. User-scoped so agents can only write logs they own. - **Auditor (site):** read. - `boundary_log` is excluded from org-admin, org-member, and org-service-account `allPermsExcept` calls for consistency with `ResourceBoundaryUsage`. - **System subjects:** - **DB Purge** (`SubjectTypeDBPurge`): delete. The only subject that can remove boundary logs. - **Workspace agent scope**: `ResourceBoundaryLog` with wildcard ID in the agent scope allow-list (necessary for creation since no pre-existing ID exists). User-level role scoping prevents deployment-wide access. - **DB migration** (`000510_boundary_log_scopes`): add `boundary_log:*`, `boundary_log:create`, `boundary_log:delete`, `boundary_log:read` enum values to `api_key_scope`. - **Test coverage**: `BoundaryLogCreate` (user-scoped, only matching owner succeeds), `BoundaryLogDelete` (all human roles denied), `BoundaryLogRead` (owner + auditor). dbauthz mock tests set up workspace agent lookups for owner derivation. - **Generated docs**: update OpenAPI specs, API reference docs, and frontend type definitions. --------- Co-authored-by: Muhammad Danish <mdanishkhdev@gmail.com> Co-authored-by: Coder Agents <coder-agents-review[bot]@users.noreply.github.com>
This commit is contained in:
co-authored by
Muhammad Danish
Coder Agents
parent
88060b846e
commit
a586b7e5e0
@@ -0,0 +1 @@
|
||||
-- No-op for boundary_log scopes: keep enum values to avoid dependency churn.
|
||||
@@ -0,0 +1,5 @@
|
||||
-- Add boundary_log scopes for RBAC.
|
||||
ALTER TYPE api_key_scope ADD VALUE IF NOT EXISTS 'boundary_log:*';
|
||||
ALTER TYPE api_key_scope ADD VALUE IF NOT EXISTS 'boundary_log:create';
|
||||
ALTER TYPE api_key_scope ADD VALUE IF NOT EXISTS 'boundary_log:delete';
|
||||
ALTER TYPE api_key_scope ADD VALUE IF NOT EXISTS 'boundary_log:read';
|
||||
@@ -0,0 +1,2 @@
|
||||
ALTER TABLE boundary_sessions DROP CONSTRAINT IF EXISTS boundary_sessions_owner_id_fkey;
|
||||
ALTER TABLE boundary_sessions DROP COLUMN IF EXISTS owner_id;
|
||||
@@ -0,0 +1,28 @@
|
||||
-- Add owner_id to boundary_sessions to avoid expensive JOINs when
|
||||
-- deriving the workspace owner for RBAC checks during log insertion.
|
||||
ALTER TABLE boundary_sessions ADD COLUMN owner_id uuid;
|
||||
|
||||
COMMENT ON COLUMN boundary_sessions.owner_id IS 'The ID of the user who owns the workspace. NULL if the user has been deleted.';
|
||||
|
||||
-- Backfill owner_id from the workspace agent -> workspace -> owner chain.
|
||||
-- Soft-deleted agents and workspaces are included so that their audit
|
||||
-- data is preserved.
|
||||
UPDATE boundary_sessions bs
|
||||
SET owner_id = w.owner_id
|
||||
FROM workspace_agents wa
|
||||
JOIN workspace_resources wr ON wa.resource_id = wr.id
|
||||
JOIN provisioner_jobs pj ON wr.job_id = pj.id
|
||||
JOIN workspace_builds wb ON pj.id = wb.job_id
|
||||
JOIN workspaces w ON wb.workspace_id = w.id
|
||||
WHERE wa.id = bs.workspace_agent_id
|
||||
AND pj.type = 'workspace_build';
|
||||
|
||||
-- Delete any sessions that could not be backfilled (orphaned data
|
||||
-- with no resolvable workspace agent or workspace build chain).
|
||||
DELETE FROM boundary_sessions WHERE owner_id IS NULL;
|
||||
|
||||
-- Add FK constraint. SET NULL preserves audit data when a user is
|
||||
-- hard-deleted; the session and its logs survive with a NULL owner.
|
||||
ALTER TABLE boundary_sessions
|
||||
ADD CONSTRAINT boundary_sessions_owner_id_fkey
|
||||
FOREIGN KEY (owner_id) REFERENCES users(id) ON DELETE SET NULL;
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
-- Re-insert boundary session and log fixture data after migration 000511
|
||||
-- deletes orphaned rows (the original fixture's workspace_agent links to a
|
||||
-- template_version_import job, not a workspace_build, so the backfill
|
||||
-- cannot resolve the owner).
|
||||
|
||||
INSERT INTO boundary_sessions (
|
||||
id,
|
||||
workspace_agent_id,
|
||||
confined_process_name,
|
||||
started_at,
|
||||
updated_at,
|
||||
owner_id
|
||||
) VALUES (
|
||||
'a1b2c3d4-e5f6-4890-abcd-ef1234567890',
|
||||
'45e89705-e09d-4850-bcec-f9a937f5d78d',
|
||||
'claude-code',
|
||||
'2026-04-01 10:00:00+00',
|
||||
'2026-04-01 10:00:00+00',
|
||||
'30095c71-380b-457a-8995-97b8ee6e5307'
|
||||
);
|
||||
|
||||
INSERT INTO boundary_logs (
|
||||
id,
|
||||
session_id,
|
||||
sequence_number,
|
||||
captured_at,
|
||||
created_at,
|
||||
proto,
|
||||
method,
|
||||
detail,
|
||||
matched_rule
|
||||
) VALUES (
|
||||
'b2c3d4e5-f6a7-4901-bcde-f12345678901',
|
||||
'a1b2c3d4-e5f6-4890-abcd-ef1234567890',
|
||||
0,
|
||||
'2026-04-01 10:00:01+00',
|
||||
'2026-04-01 10:00:00+00',
|
||||
'http',
|
||||
'GET',
|
||||
'https://api.anthropic.com/v1/messages',
|
||||
'domain=api.anthropic.com'
|
||||
);
|
||||
Reference in New Issue
Block a user