Deny your first call
You add your own user to the denylist control in the Admin Portal. The same weather call from Make your first governed call is then refused, and Access Activity records why. Then you remove the entry and the call works again. You change control data only. You write no Rego and restart nothing.
This page is step 6, the last step of the First environment track.
Before you start
- You finished Make your first governed call, and your client is still connected.
- You noted your user id from the Access Activity row of that call.
Deny the call
Total time: 4 min
Add your user to the denylist
1 minIn the Admin Portal, under Operate, select Policy, then the Controls tab. Find Denylist and select Configure.
Under subjects, the page lists the user ids it has seen. Select yours. It moves into the box. Select Save.
You should see. A green message reads Saved. OPA picks this up on its next bundle poll.
Repeat the call
1 minWait a few seconds for the policy engine to load the change. Ask your client for the weather again.
Use the policyarc current_weather tool for latitude 43.65 and longitude -79.38.You do not sign in again. Your token is still valid, but the gateway asks the authorization server about every call, and policy now refuses your user.
If your client does try to sign in again while you are on the denylist, the sign-in itself fails. The client receives the OAuth error
access_denied.You should see. The tool returns an error with the text HTTP 403: Access denied.
Read the reason in Access Activity
1 minOpen Access Activity. The newest rows are your denied call.
- A denied
/introspectrow that readsasfollowed by your user id. - A denied
/gateway/weather-openmeteo/v1/forecastrow. Select it. Its Policy Decision shows"reason" : "pdp_deny"and"pdp_reason" : "subject_denied". The PDP is the policy decision point, the engine that decided.
The denied gateway row shows the client as
unknownand names no user. The/introspectrow next to it carries your user id.You should see. The policy decision of the newest denied /gateway/weather-openmeteo/v1/forecast row shows pdp_reason subject_denied.
- A denied
Roll the change back
1 minOpen Denylist again, clear the subjects box, and select Save. Wait a few seconds and ask for the weather again.
You should see. The weather call returns current conditions again, and the newest /introspect row is allowed.
Script the same change
The Save button writes one row of control data named pbac.operator.controls.denylist. You can write it with the Admin API instead. Copy the Admin API key from your environment page in the dashboard with Reveal key. We have not run the dashboard steps. We ran the two blocks below against a local instance with its admin key, and both passed. Set three values first.
export POLICYARC_URL="https://your-environment.example"
export POLICYARC_ADMIN_KEY="paste the Admin API key"
export POLICYARC_SUBJECT="paste your user id"
Deny the user.
row=$(curl -fsS -X PUT "$POLICYARC_URL/admin/api/policy-data/by-key?dataKey=pbac.operator.controls.denylist" \
-H "X-Admin-API-Key: $POLICYARC_ADMIN_KEY" \
-H 'Content-Type: application/json' \
-d "{\"dataKey\":\"pbac.operator.controls.denylist\",\"inBundle\":true,\"payload\":{\"subjects\":[\"$POLICYARC_SUBJECT\"]}}")
echo "$row"
grep -qF '"dataKey":"pbac.operator.controls.denylist"' <<<"$row" || { echo 'The stored row is not the denylist row' >&2; false; }
grep -qF "$POLICYARC_SUBJECT" <<<"$row" || { echo 'The stored row does not list your user id' >&2; false; }
Roll it back.
row=$(curl -fsS -X PUT "$POLICYARC_URL/admin/api/policy-data/by-key?dataKey=pbac.operator.controls.denylist" \
-H "X-Admin-API-Key: $POLICYARC_ADMIN_KEY" \
-H 'Content-Type: application/json' \
-d '{"dataKey":"pbac.operator.controls.denylist","inBundle":true,"payload":{"subjects":[]}}')
echo "$row"
grep -qF '"dataKey":"pbac.operator.controls.denylist"' <<<"$row" || { echo 'The stored row is not the denylist row' >&2; false; }
if grep -qF "$POLICYARC_SUBJECT" <<<"$row"; then echo 'The stored row still lists your user id' >&2; false; fi
Each command prints the row the API stored and fails if it is not the row you meant. Each call replaces the whole row, as Save does. If the row holds other entries, include them in the payload.
What happened
A control is a piece of policy that ships with PolicyArc and reads its settings from a row of control data. The denylist control refuses any client or subject listed in its row. When the gateway sent your token to introspection, the authorization server ran the token policy again for this tool. The denylist matched your subject and the decision came back deny with the reason subject_denied. The gateway then refused the call before it reached Open-Meteo.
The other controls work the same way. Each one has a row, a settings shape, and the reason codes it can emit. Controls and segments explains the model.
Check your work
If the call still works after the first step, see Troubleshooting.
Send feedback about this page