feat: add account roles audit and task authorization
This commit is contained in:
1 parent
337aaf7c88
commit
191c1a1aad
15 files changed
+4961
-457
No files matched your search
@@ -0,0 +1,100 @@
|
||||
-- Fixed-scope account roles, audit attribution, and reversible task archive.
|
||||
-- Existing accounts remain administrators; no organization/tenant UI is added.
|
||||
|
||||
ALTER TABLE users
|
||||
DROP CONSTRAINT IF EXISTS users_role_check;
|
||||
|
||||
ALTER TABLE users
|
||||
ADD CONSTRAINT users_role_check CHECK (role IN ('admin', 'user'));
|
||||
|
||||
ALTER TABLE users
|
||||
ADD COLUMN IF NOT EXISTS must_change_password boolean NOT NULL DEFAULT false,
|
||||
ADD COLUMN IF NOT EXISTS password_changed_at timestamptz NOT NULL DEFAULT now();
|
||||
|
||||
-- User-supplied idempotency keys are account-scoped. System/AgentBus keys
|
||||
-- remain deployment-scoped through the NULL actor partial index.
|
||||
ALTER TABLE tasks
|
||||
DROP CONSTRAINT IF EXISTS tasks_organization_id_idempotency_key_key;
|
||||
|
||||
ALTER TABLE idempotency_keys
|
||||
DROP CONSTRAINT IF EXISTS idempotency_keys_organization_id_scope_idempotency_key_key;
|
||||
|
||||
ALTER TABLE idempotency_keys
|
||||
ADD COLUMN IF NOT EXISTS actor_user_id uuid REFERENCES users(id);
|
||||
|
||||
UPDATE idempotency_keys i
|
||||
SET actor_user_id = t.created_by
|
||||
FROM tasks t
|
||||
WHERE i.task_id = t.id
|
||||
AND i.actor_user_id IS NULL
|
||||
AND t.source = 'manual';
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idempotency_keys_actor_unique_idx
|
||||
ON idempotency_keys (organization_id, scope, idempotency_key, actor_user_id)
|
||||
WHERE actor_user_id IS NOT NULL;
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idempotency_keys_system_unique_idx
|
||||
ON idempotency_keys (organization_id, scope, idempotency_key)
|
||||
WHERE actor_user_id IS NULL;
|
||||
|
||||
ALTER TABLE agent_session_messages
|
||||
ADD COLUMN IF NOT EXISTS actor_user_id uuid REFERENCES users(id),
|
||||
ADD COLUMN IF NOT EXISTS input_source text;
|
||||
|
||||
ALTER TABLE agent_session_messages
|
||||
DROP CONSTRAINT IF EXISTS agent_session_messages_input_source_check;
|
||||
|
||||
ALTER TABLE agent_session_messages
|
||||
ADD CONSTRAINT agent_session_messages_input_source_check
|
||||
CHECK (input_source IS NULL OR input_source IN ('manual', 'agentbus', 'reparse', 'system'));
|
||||
|
||||
-- Only the initial input has a provable historical platform actor. Do not
|
||||
-- invent actors for later turns that predate explicit attribution.
|
||||
UPDATE agent_session_messages m
|
||||
SET actor_user_id = t.created_by,
|
||||
input_source = CASE WHEN t.source = 'agentbus' THEN 'agentbus' ELSE 'manual' END
|
||||
FROM tasks t
|
||||
WHERE m.task_id = t.id
|
||||
AND m.role = 'user'
|
||||
AND m.turn_no = 1
|
||||
AND (m.actor_user_id IS NULL OR m.input_source IS NULL);
|
||||
|
||||
ALTER TABLE task_input_attachments
|
||||
ADD COLUMN IF NOT EXISTS created_by uuid REFERENCES users(id);
|
||||
|
||||
UPDATE task_input_attachments a
|
||||
SET created_by = t.created_by
|
||||
FROM tasks t
|
||||
WHERE a.task_id = t.id
|
||||
AND a.created_by IS NULL
|
||||
AND a.source = 'manual';
|
||||
|
||||
ALTER TABLE tasks
|
||||
ADD COLUMN IF NOT EXISTS archived_at timestamptz,
|
||||
ADD COLUMN IF NOT EXISTS archived_by uuid REFERENCES users(id),
|
||||
ADD COLUMN IF NOT EXISTS archive_reason text;
|
||||
|
||||
ALTER TABLE tasks
|
||||
DROP CONSTRAINT IF EXISTS tasks_archive_reason_length_check;
|
||||
|
||||
ALTER TABLE tasks
|
||||
ADD CONSTRAINT tasks_archive_reason_length_check
|
||||
CHECK (archive_reason IS NULL OR char_length(archive_reason) <= 500);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS users_org_role_active_idx
|
||||
ON users (organization_id, role, is_active, username);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS tasks_owner_visible_created_idx
|
||||
ON tasks (organization_id, created_by, created_at DESC, id DESC)
|
||||
WHERE archived_at IS NULL;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS tasks_archive_created_idx
|
||||
ON tasks (organization_id, archived_at DESC, created_at DESC, id DESC)
|
||||
WHERE archived_at IS NOT NULL;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS agent_session_messages_actor_idx
|
||||
ON agent_session_messages (organization_id, actor_user_id, created_at DESC)
|
||||
WHERE actor_user_id IS NOT NULL;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS audit_events_actor_created_idx
|
||||
ON audit_events (organization_id, actor_user_id, created_at DESC);
|
||||
Reference in new issue
Block a user