Skip to main content

Security posture

The Security posture screen lets you read the protections of the platform and its automated pass, warn and fail checks, change the security settings of your tenant (prompt injection, untrusted content, links, egress) and follow the recent security events. Portal path: /security/posture, menu Security and governance > Security posture. It is used by security officers (security_officer) and tenant administrators (tenant_admin).

What the screen shows​

The screen is built by portal/src/screens/security-posture.tsx and reads four routes.

  • Header line: the Environment badge (for example prod) and the Generated date of the posture, both from GET /v1/security/posture.
  • Summary cards: three counters, Passing, Warnings and Failing (field summary of the posture).
  • Checks card: the checks grouped by category, sorted by name. Each line shows a status badge (Pass, Warn or Fail), the message in the language of the portal (message_en or message_fr), the identifier of the check in monospace and, when present, a severity badge (Critical, High, Medium, Low). Without any check: "No check reported".
  • Protections card: one tile per protection of the platform (for example Security headers, HSTS, Allowed hosts, Trusted proxies, Body limits, Rate limits, Authentication, CORS origins, Egress policy, API docs exposed). A boolean shows Enabled or Disabled, a list shows one badge per value, an object is shown as JSON. Without any protection: "No protection reported".
  • Tenant security settings card ("Partial update, audited as security.settings.update."), loaded by GET /v1/security/settings:
FieldValuesDefaultMeaning
Prompt injection modeOff, Detect, BlockDetectoff: no check, detect: audit only, block: refuse the request.
Links in model outputAllow, Strip untrustedStrip untrustedstrip_untrusted removes links to hosts outside the allowlist.
Wrap untrusted contentswitchonTool results and documents are delimited as untrusted data.
Allowed link hostsone host per lineemptyHosts whose links stay in the model output.
Allowed egress hostsone host or *.suffix per lineemptyHosts the tenant may call. Empty: no tenant restriction.
  • Recent security events card: a table with the columns When, Action, Actor and Outcome. The portal reads the last 200 audit events (GET /v1/audit/events) and keeps the 50 latest whose action starts with security.. Without any event: "No security event".

Actions​

Button or actionWhat it doesAPI callRoles
Refresh (page header)Reads the posture again: summary, checks and protections.GET /v1/security/posturesecurity_officer, tenant_admin
Retry (error state of a card)Reads the failed card again.The route of the cardSame as the card
Save settingsSends the five settings of the form as a partial update, then reloads the posture and the events. Message "Security settings saved".PUT /v1/security/settingstenant_admin, security_officer
ResetPuts the form back to the values last loaded from the API, without any call.NoneEvery reader of the screen
Loading of Tenant security settingsReads the current settings of the tenant.GET /v1/security/settingstenant_admin, security_officer
Loading of Recent security eventsReads the audit events and filters the security.* actions.GET /v1/audit/eventsauditor, security_officer, tenant_admin, platform_admin

Roles​

The portal hides no part of this screen: the Control Plane decides. On the server side (services/control-plane/src/eai/domains/security/__init__.py), the posture and the settings both require security_officer or tenant_admin, and platform_admin passes every role check. The settings need a tenant: a principal without tenant gets tenant_required. The events card follows the readers of the audit log (ROLES.auditReaders in portal/src/lib/kit.ts: auditor, security_officer, tenant_admin, platform_admin). Every save is written in the audit log as security.settings.update with the changed fields.

Typical tasks​

Review the posture before a go live​

  1. Open the screen. The posture gathers the checks of the platform in one place. Menu Security and governance > Security posture. Expected result: the header shows the environment and the generation date, then the three counters. If it fails: forbidden (HTTP 403) means you hold neither security_officer nor tenant_admin.
  2. Read the failing checks first. A Fail check is a protection that is missing or misconfigured. Look in the Checks card for the Fail badges and note their identifier. Expected result: the list of the checks to fix, with their severity. If it fails: "No check reported" means the API returned an empty list; click Refresh.
  3. Check the protections. They show the effective configuration of the API (headers, hosts, limits, CORS). Read the Protections card. Expected result: Enabled on the protections you expect, the allowed hosts and CORS origins of your deployment. If it fails: a protection shown Disabled is changed in the configuration of the Control Plane, not from this screen (see the security configuration page).
  4. Refresh after a fix. The posture is computed on each read. Click Refresh. Expected result: the counter Failing goes down. If it fails: the configuration change was not applied to the running Control Plane.

Block prompt injections for the tenant​

  1. Choose the mode. block refuses a request whose content looks like an injection, detect only audits it. In Tenant security settings, set Prompt injection mode to Block. Expected result: the select shows Block. If it fails: the card shows "Sign in with a tenant to edit its settings." when the API answers 400 or 404; sign in with an account of the tenant.
  2. Keep the untrusted content wrapped. Wrapping delimits tool results and documents as data, not as instructions. Leave Wrap untrusted content on. Expected result: the switch is on.
  3. Save. Click Save settings. Expected result: the message "Security settings saved", and a security.settings.update line in Recent security events. If it fails: forbidden means a missing role; an error under a field means the value of that field was refused.

Restrict the hosts the tenant can call​

  1. List the hosts. Only public host names are accepted, one per line, or *.suffix for a whole domain. Fill Allowed egress hosts, for example api.openai.com. Expected result: one host per line in the field. If it fails: nothing to do at this step.
  2. Save. Click Save settings. Expected result: "Security settings saved". If it fails: "Invalid public host name" under the field means an IP address, localhost or an internal suffix (.local, .internal, .svc, .corp...) was entered; "Expected a list of at most 200 host names." means the list is too long.
  3. Verify. An outbound call to another host is now refused. Watch Recent security events. Expected result: the egress denials appear there. If it fails: click Retry on the events card; forbidden on this card means you are not a reader of the audit log.

Troubleshooting​

SymptomCauseFix
Error state with forbidden (HTTP 403) on the postureYour roles are neither security_officer nor tenant_admin.Ask a tenant administrator for one of these roles.
"Sign in with a tenant to edit its settings."GET /v1/security/settings answered 400 or 404 (for example unknown_tenant).Sign in with an account attached to a tenant.
Error tenant_required in the settings cardThe principal acts without a tenant (HTTP 403).Use an account or an API key of the tenant.
Red message under a field after Save settingsvalidation_error (HTTP 422) with details.field: unknown setting, value outside off, detect, block or allow, strip_untrusted, invalid public host name, more than 200 hosts.Fix the field named in the message and save again.
Recent security events shows forbiddenGET /v1/audit/events needs auditor, security_officer, tenant_admin or platform_admin.Ask for a role that reads the audit log.
"No security event"No audit event with an action security.* among the last 200 events.Normal on a quiet tenant; see the full log on the audit events screen.
"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.