Skip to main content

Reference

Technical specification for the OPA Backend plugin — configuration keys and HTTP endpoints.

Configuration

All keys live under openPolicyAgent in app-config.yaml.

KeyTypeDefaultDescription
openPolicyAgent.baseUrlstringhttp://localhost:8181 for /opa-authz, no default for /entity-checkerBase URL of your OPA server. Set this explicitly — /entity-checker returns a 500 if it is missing.
openPolicyAgent.entityChecker.enabledbooleanfalseMounts the /entity-checker route when true.
openPolicyAgent.entityChecker.policyEntryPointstringRego entry point for entity validation. Required when entityChecker.enabled is true. Example: entity_checker/violation.
openPolicyAgent.policyViewer.enabledbooleanfalseMounts the /get-policy route when true.

Entry point format

Entry points map directly to Rego package and rule names. The string entity_checker/violation maps to package entity_checker, rule violation.


HTTP Endpoints

All routes are mounted under /api/opa.


GET /api/opa/health

Health check endpoint.

  • Auth: unauthenticated
  • Always mounted: yes

Response

{ "status": "ok" }

POST /api/opa/opa-authz

Evaluates an OPA policy and returns the result. Used by opa-authz-react.

  • Auth: requires user credentials (Backstage user token)
  • Always mounted: yes — no config flag required

Request body

{
"entryPoint": "my_policy/decision",
"input": {
"action": "read",
"resourceType": "catalog-entity"
},
"includeUserEntity": false
}
FieldTypeRequiredDescription
entryPointstringYesRego entry point to evaluate (e.g. my_policy/decision).
inputobjectYesArbitrary input data forwarded to OPA.
includeUserEntitybooleanNoWhen true, fetches the full Backstage User entity from the catalog and adds it to the OPA input as userEntity.

Auto-injected fields

The plugin automatically adds the following to input before forwarding to OPA, regardless of what the caller sends:

FieldTypeDescription
userEntityRefstringBackstage entity ref of the calling user (e.g. user:default/jane).
ownershipEntityRefsstring[]All entity refs the user owns.
userEntityEntity | nullFull Backstage User entity resolved from the catalog. Only present when includeUserEntity: true. Always set by the backend — any userEntity supplied by the caller is silently stripped.

Response

The raw response body from OPA's /v1/data/<entryPoint> endpoint, passed through unchanged. Shape depends on your Rego policy.

Error responses

StatusCause
400Request body failed schema validation. Response includes error: "Invalid request body" and a details object with formErrors (top-level) and fieldErrors (per-field).
500OPA server unreachable, or error fetching user entity from catalog.

POST /api/opa/entity-checker

Validates a Backstage entity against an OPA policy. Used by opa-entity-checker.

  • Auth: requires a valid Backstage token (user or service-to-service); enforced by the framework
  • Requires config: openPolicyAgent.entityChecker.enabled: true and openPolicyAgent.entityChecker.policyEntryPoint

Request body

{
"input": {
/* Backstage Entity object */
}
}

Response

{
"result": [
{
"decision_id": "abc123",
"check_title": "Owner must be set",
"level": "error",
"message": "Entity is missing an owner annotation."
}
]
}
FieldTypeDescription
resultOpaResult[]Array of violation messages returned by OPA. Empty array means the entity passes all checks.
result[].level"error" | "warning" | "info"Severity of the violation.
result[].messagestringHuman-readable violation description.
result[].check_titlestringOptional title for the check.
result[].decision_idstringOptional OPA decision ID for tracing.

Error responses

StatusCause
400Missing entity metadata in request body.
500baseUrl or policyEntryPoint not configured, or OPA server error.

GET /api/opa/get-policy

Fetches the raw content of a Rego policy file from a URL. Used by opa-policies.

  • Auth: requires a valid Backstage token (user or service-to-service); enforced by the framework
  • Requires config: openPolicyAgent.policyViewer.enabled: true
  • Does not call OPA — reads the file via Backstage's UrlReader service

Query parameters

ParameterTypeRequiredDescription
opaPolicystringYesURL of the .rego policy file to fetch (e.g. a raw GitHub URL). Omitting this will result in a 500 error.

Response

{
"opaPolicyContent": "package my_policy\n\ndefault allow = false\n..."
}

Edge cases

ScenarioStatusBody
opaPolicy query param missing500Error passed to middleware
Policy file not found (NotFoundError)200{}opaPolicyContent field absent
Other fetch error (network, auth)500Error passed to middleware