Decisions log
The Decisions log screen lets you read every policy decision taken by the platform for the tenant, filter them by action and by outcome, and open the full record of one decision. Portal path: /security/decisions, menu Security and governance > Decisions log. It is used by security officers, tenant administrators and auditors who explain why an action was allowed or refused.
What the screen shows
The screen (Decisions in portal/src/screens/security.tsx) shows one table, Decisions, read from GET /v1/policies/decisions, newest first, 50 rows per request with a cursor to load more.
| Column | Content |
|---|---|
| Id | Identifier of the decision. |
| Action | Action evaluated, for example model.invoke or tool.invoke. |
| Subject id | Who asked (subject.id). |
| Resource type | Type of the resource (resource.type). |
| Resource id | Identifier of the resource (resource.id). |
| Allowed | Yes or No. |
| Reasons | Reasons returned by the policy engine. |
| Evaluated | Date of the evaluation. |
Above the table, two filters and the Filter button: Action (free text, exact match) and Allowed (all, true, false). A click on a row opens a side panel with the JSON of the decision (subject, resource, context, obligations). Empty table: "No decision recorded", "Decisions are recorded on every governed action."
Actions
| Button or action | What it does | API call | Roles |
|---|---|---|---|
| Filter | Applies the Action and Allowed filters and reads the first page again. | GET /v1/policies/decisions (query action, allow) | tenant_admin, security_officer, auditor |
| Next page of the table | Loads the next 50 decisions with the cursor. | GET /v1/policies/decisions (query cursor) | Same |
| Refresh icon | Reads the list again. | GET /v1/policies/decisions | Same |
| Row click or View details | Shows the row in a side panel, without another call. | None | Same |
| Retry (error state) | Reads the list again after an error. | GET /v1/policies/decisions | Same |
Roles
The portal hides nothing on this screen. The Control Plane requires tenant_admin, security_officer or auditor (require_role(*ADMIN_ROLES, "auditor") in services/control-plane/src/eai/domains/policies/__init__.py), and a tenant; platform_admin passes every role check. The decisions are written by the platform itself on every governed action: no one creates or edits a decision from the portal.
Typical tasks
Explain why a request was refused
- Filter the refusals. A refusal is a decision with
allow = false. Set Allowed tofalseand click Filter. Expected result: only the refused decisions are listed. If it fails:forbidden(HTTP 403) means your roles are neithertenant_admin,security_officernorauditor. - Narrow to the action. Enter the action, for example
model.invoke, in Action, then Filter. Expected result: the refusals of that action. If it fails: an empty table means the text does not match exactly; copy the action from a row. - Read the decision. The reasons and the context tell which rule decided. Click the row. Expected result: the side panel with
reasons,subject,resourceandcontext. If it fails: nothing to retry, the panel uses the row already loaded. - Reproduce it. To test a fix, copy the request into the evaluator of the Policies screen or into the Policy simulator. Expected result: the same outcome before the fix, the new one after. If it fails: see the Policies page.
Review the decisions of an audit period
- Open the log. Every governed action leaves a decision. Menu Security and governance > Decisions log. Expected result: the latest decisions first. If it fails:
tenant_requiredmeans the account has no tenant. - Page back. Older decisions come with the cursor. Go to the next pages at the bottom of the table. Expected result: older rows are loaded, 50 at a time. If it fails:
invalid_cursorafter a long pause; click the refresh icon and page again.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
Error state forbidden (HTTP 403) | The route needs tenant_admin, security_officer or auditor. | Ask for one of these roles. |
tenant_required (HTTP 403) | The account acts without a tenant. | Sign in with an account of the tenant. |
| "No decision recorded" | No governed action yet, or the filters exclude every row. | Clear the filters (choose all) and click Filter. |
validation_error (HTTP 422) after Filter | A value of Allowed other than true or false was sent. | Choose a value from the list. |
| "The Control Plane API cannot be reached" | The API is down or the API address of the portal is wrong. | Check the Control Plane and the NEXT_PUBLIC_EAI_API_URL setting of the portal. |