mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
feat(coderd/database): add boundary_sessions and boundary_logs tables (#25441)
RFC: [Bridge ↔ Boundaries Correlation RFC](https://www.notion.so/coderhq/Gateway-and-Firewall-Correlation-RFC-31ad579be592803aa8b3d48348ccdde9) Add up/down migrations and matching sqlc queries for persisting Boundary audit events, as specified in the Bridge/Boundaries Correlation RFC. **Tables:** - `boundary_sessions`: session metadata with `workspace_agent_id` FK, `confined_process_name`, and timestamps (`started_at`, `updated_at`). ID is externally supplied by the Boundary process (no DB-side default). Created lazily when the first log for a session arrives. - `boundary_logs`: individual audit events with `session_id` FK, `sequence_number` (INT, primary ordering key), protocol/method/detail fields, and `matched_rule` (nullable; non-NULL implies allowed). **Indexes (per RFC):** - `(session_id, sequence_number)` for the ordering query path - `(captured_at)` for the retention purge path **Queries:** - `InsertBoundarySession` / `GetBoundarySessionByID` - `InsertBoundaryLog` / `GetBoundaryLogByID` - `ListBoundaryLogsBySessionID` with nullable `seq_after`/`seq_before` exclusive bounds for fetching events between two known interception sequence numbers - `DeleteOldBoundaryLogs` with row limit to avoid long-running transactions **Also includes:** dbgen helpers (`BoundarySession`, `BoundaryLog`), dbauthz implementations (reads gated on `ResourceAuditLog`, deletes on `ResourceSystem`), and all generated wrappers (dbmock, dbmetrics). No callers yet. A follow-up PR will add the dedicated `boundary_log` RBAC resource type. > Generated by Coder Agents
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
DROP INDEX IF EXISTS idx_boundary_logs_captured_at;
|
||||
DROP INDEX IF EXISTS idx_boundary_logs_session_seq;
|
||||
DROP TABLE IF EXISTS boundary_logs;
|
||||
DROP TABLE IF EXISTS boundary_sessions;
|
||||
@@ -0,0 +1,43 @@
|
||||
CREATE TABLE boundary_sessions (
|
||||
id UUID PRIMARY KEY,
|
||||
workspace_agent_id UUID NOT NULL REFERENCES workspace_agents(id),
|
||||
confined_process_name TEXT NOT NULL,
|
||||
started_at TIMESTAMPTZ NOT NULL,
|
||||
updated_at TIMESTAMPTZ NOT NULL
|
||||
);
|
||||
|
||||
COMMENT ON TABLE boundary_sessions IS 'Boundary session metadata. Each row represents a single invocation of a Boundary process wrapping a confined agent.';
|
||||
COMMENT ON COLUMN boundary_sessions.id IS 'The unique session ID generated by the Boundary process on startup.';
|
||||
COMMENT ON COLUMN boundary_sessions.workspace_agent_id IS 'The workspace agent that this Boundary session is associated with.';
|
||||
COMMENT ON COLUMN boundary_sessions.confined_process_name IS 'Name of the confined process (e.g. claude-code, codex, copilot).';
|
||||
COMMENT ON COLUMN boundary_sessions.started_at IS 'Time when the first log for this session was received by coderd.';
|
||||
COMMENT ON COLUMN boundary_sessions.updated_at IS 'Time when the session was last updated.';
|
||||
|
||||
CREATE TABLE boundary_logs (
|
||||
id UUID NOT NULL,
|
||||
session_id UUID NOT NULL REFERENCES boundary_sessions(id) ON DELETE CASCADE,
|
||||
sequence_number INT NOT NULL CHECK (sequence_number >= 0),
|
||||
captured_at TIMESTAMPTZ NOT NULL,
|
||||
created_at TIMESTAMPTZ NOT NULL,
|
||||
proto TEXT NOT NULL DEFAULT '',
|
||||
method TEXT NOT NULL DEFAULT '',
|
||||
detail TEXT NOT NULL DEFAULT '',
|
||||
matched_rule TEXT,
|
||||
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
|
||||
COMMENT ON TABLE boundary_logs IS 'Persisted boundary audit events. Each row is a single audit event processed by a Boundary proxy.';
|
||||
COMMENT ON COLUMN boundary_logs.session_id IS 'The session ID generated by the Boundary process on startup. Groups all events from one invocation.';
|
||||
COMMENT ON COLUMN boundary_logs.sequence_number IS 'Monotonically increasing integer assigned by Boundary, starting at 0 per session. Primary ordering key when Boundary is in use.';
|
||||
COMMENT ON COLUMN boundary_logs.captured_at IS 'When the log was sent to the DB.';
|
||||
COMMENT ON COLUMN boundary_logs.created_at IS 'When the event happened on the workspace.';
|
||||
COMMENT ON COLUMN boundary_logs.proto IS 'The protocol of the audited action. e.g. http, dns, git, fs.';
|
||||
COMMENT ON COLUMN boundary_logs.method IS 'The operation within the protocol. e.g. GET/POST for http, clone for git, A for dns, read/write for fs.';
|
||||
COMMENT ON COLUMN boundary_logs.detail IS 'Protocol-specific detail. e.g. the full URL for http, the hostname for dns, the path for fs.';
|
||||
COMMENT ON COLUMN boundary_logs.matched_rule IS 'The allow-list rule that matched. NULL when the request was denied; non-NULL implies the request was allowed.';
|
||||
|
||||
-- Ordering query path: list events for a session, sorted by sequence number.
|
||||
CREATE INDEX idx_boundary_logs_session_seq ON boundary_logs (session_id, sequence_number);
|
||||
-- Retention purge path: delete old rows by capture time.
|
||||
CREATE INDEX idx_boundary_logs_captured_at ON boundary_logs (captured_at);
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
INSERT INTO boundary_sessions (
|
||||
id,
|
||||
workspace_agent_id,
|
||||
confined_process_name,
|
||||
started_at,
|
||||
updated_at
|
||||
) 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'
|
||||
);
|
||||
|
||||
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