## TL;DR
A 403 means the agent authenticated fine but its role lacks the permission: RBAC said no. Check which role the agent's credentials carry and which permission the endpoint needs, then grant the least privilege that covers the agent's job. Do not hand the agent admin; scope the role to the DAGs and actions it actually needs.

```text
airflow RBAC 403 when agent tried the REST API, request failed
```

## Use this when
- Agent Airflow API calls fail with 403.
- The same credential authenticates successfully.
- It worked before an Airflow upgrade or RBAC change.

## Not for this skill when
- Calls fail with 401. That is authentication, not authorization.
- The UI also denies access. Check the user's role the same way.

## Steps
1. Note the exact endpoint and action that 403d. Note the denied action. Verify: the gap is precise
2. Check the agent's role and its permissions in the Airflow RBAC UI. Note the role's grants. Verify: the current access is mapped
3. Find the minimum permission covering the action: often a DAG-scoped role, not admin. Note the least privilege. Verify: the grant is scoped
4. Grant it, or have an admin grant it, and re-try the call. Note the success. Verify: the access works
5. Document the agent's role contract: what it can do and why. Note the documentation. Verify: the access is reviewable

## Variant phrasings
### airflow api 403 forbidden rbac
The code-shaped search.
### airflow agent api permissions
The setup phrasing.

Compatibility: Airflow 2.x RBAC via Flask-AppBuilder. Permission names are stable across 2.x.

## Why it happens
Airflow's API enforces the same RBAC as the UI: every endpoint checks the caller's role. Agents usually get a service credential with a narrow role, and the first time the agent tries something outside that role, 403. The fix is boring on purpose: map the action to the permission, grant the permission. The temptation to grant admin to make the 403s stop creates an agent that can do anything, which is how a compromised or confused agent becomes a disaster.

## Edge cases / pitfalls
- Some endpoints need permissions that are not obvious from the name. The RBAC UI's permission list is the source of truth.
- Upgrades can rename or split permissions, silently narrowing old roles. Re-verify agent roles after upgrades.
- A 403 on one DAG but not another is DAG-scoped permissions working correctly. Scope the role per DAG deliberately.
- Service credentials with expiring tokens 403 confusingly on some clients. Rule out expiry before reworking roles.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_k_6yupxEgOzqj648l09uYA
