Skip to main content

Local Development

The OPA Node service has a self-contained dev setup that lets you run and test it in isolation — no full Backstage app required.

Prerequisites​

  • Node 22 or 24
  • A running OPA server at http://localhost:8181 — run docker-compose up -d from the repo root
  • Dependencies installed: yarn install
  • openPolicyAgent.baseUrl set in app-config.yaml — the root config in this repo already has it. If running outside this repo, add:
openPolicyAgent:
baseUrl: 'http://localhost:8181'

Starting the service​

yarn workspace @parsifal-m/backstage-plugin-opa-node start

The backend starts at http://localhost:7007. The dev plugin mounts a single test route at /api/opa-node-dev/evaluate.

The dev setup uses mocked Backstage services (auth, httpAuth) so no real Backstage instance or database is needed. OPA itself must still be running.

Mock authentication​

The dev backend uses mockServices.auth and mockServices.httpAuth, both permissive by design. No Authorization header is needed when testing locally.

Testing the route​

POST /api/opa-node-dev/evaluate​

Evaluates an OPA policy via the opaService. Send any input object and an entryPoint matching a policy loaded into your OPA server.

The example below targets the opa_demo policy from the repo's policies/ directory:

curl -X POST http://localhost:7007/api/opa-node-dev/evaluate \
-H 'Content-Type: application/json' \
-d '{
"input": {
"method": "GET",
"permission": { "name": "read-all-todos" }
},
"entryPoint": "opa_demo"
}'

Expected response — the allow rule in package opa_demo fires for this input:

{ "result": { "allow": true } }

To verify a deny, change method to anything other than "GET" — no rule matches and default allow := false applies:

{ "result": { "allow": false } }

The entryPoint string maps directly to the Rego package path: "opa_demo" → /v1/data/opa_demo. To target a specific rule, use the full path: "opa_demo/allow".