You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Plugin capability grants and plugin state changes are not observable after the fact. CapabilityGrant stores granted_at and granted_by_id, and the workspace audit log (ActivityEvent) exists, but nothing records the security-relevant actions that change what a plugin may do. Operators need an audit trail to answer "who granted this capability, when, and did the authorization hold".
app/models/activity_event.py::ActivityEvent - the append-only workspace event log already used for membership/role/import events (see app/services/activity.py::record_activity).
Security observability: an append-only audit trail of plugin capability and state changes, respecting existing workspace ownership and isolation. Not a rewrite of the audit system - reuse ActivityEvent/record_activity.
Technical requirements
Record a meaningful audit entry for each significant plugin security action:
Capability granted
Capability revoked
Plugin enabled
Plugin disabled
Authorization denial where appropriate (e.g., a rejected grant or a denied event delivery can be logged as an outcome without storing payloads)
Each entry should include the available attributes, consistent with how ActivityEvent is used elsewhere:
Actor (who performed the action)
Workspace
Plugin (id)
Capability (where applicable)
Action (grant/revoke/enable/disable/denied)
Timestamp
Outcome (success/denied)
Expose an owner-only view (page or API) of the plugin audit entries per workspace, reusing the existing audit authorization (owner-only, 404 for others; no existence oracle).
Retention/query: align with the existing ActivityEvent model and query patterns; do not introduce a parallel storage system. Document any pruning/retention consistent with the repository.
Security considerations
Respect existing ownership and workspace isolation: cross-workspace audit records must never be readable by another workspace's members (fail closed).
Do not log secrets or sensitive payload contents (only capability names, plugin ids, actors, and outcomes).
Audit entries are append-only; deny-by-default is logged as an outcome, not as a leak.
Acceptance criteria
Every grant/revoke/enable/disable is recorded with actor, workspace, plugin, capability (where applicable), action, timestamp, and outcome.
Authorization denials are observable as audit outcomes where appropriate.
Owner-only visibility: non-owners receive 404 for audit access.
Tests prove cross-workspace data cannot leak through audit records (a member of workspace A cannot read or observe workspace B's plugin audit entries).
Testing requirements
Unit tests: each action produces the correct audit entry.
Problem
Plugin capability grants and plugin state changes are not observable after the fact.
CapabilityGrantstoresgranted_atandgranted_by_id, and the workspace audit log (ActivityEvent) exists, but nothing records the security-relevant actions that change what a plugin may do. Operators need an audit trail to answer "who granted this capability, when, and did the authorization hold".Context
app/models/plugin.py::CapabilityGrant- storesplugin_id,workspace_id,capability,granted_at,granted_by_id.app/models/activity_event.py::ActivityEvent- the append-only workspace event log already used for membership/role/import events (seeapp/services/activity.py::record_activity).app/services/capabilities.py::CapabilityStore- grant/revoke/has_capability operations.Scope
Security observability: an append-only audit trail of plugin capability and state changes, respecting existing workspace ownership and isolation. Not a rewrite of the audit system - reuse
ActivityEvent/record_activity.Technical requirements
ActivityEventis used elsewhere:ActivityEventmodel and query patterns; do not introduce a parallel storage system. Document any pruning/retention consistent with the repository.Security considerations
Acceptance criteria
Testing requirements
Dependencies
CapabilityGrant(implemented), activity/audit log (implemented). Enable/disable recording depends on Plugin management API: install, enable, disable #163 providing those state changes.Difficulty
Medium
Priority
High