An API key with a non-admin role and per-deployment write access returns 403 No access to this deployment for the deployment it is scoped to. Reproduces with:
flatrun deployment image set my-app web nginx:latest
Error: flatrun API returned 403: No access to this deployment
CanAccessDeployment in internal/auth/models.go requires the underlying user to have a matching user_deployments row even when the API key already grants the deployment. Admin users have no rows in user_deployments (their access is implicit by role), so the user-side check fails and the request is rejected even though the key explicitly grants write.
The mirror bug is also there: a key with role admin short-circuits the function before the key's deployment cap is checked, so an admin-role key with a {my-app: write} scope silently gets access to every deployment.
The fix is to treat the API key's deployment map as the authoritative scope when the underlying user has unbounded access (admin role), and to evaluate the key's cap even when the key's effective role is admin.
An API key with a non-admin role and per-deployment write access returns
403 No access to this deploymentfor the deployment it is scoped to. Reproduces with:CanAccessDeploymentininternal/auth/models.gorequires the underlying user to have a matchinguser_deploymentsrow even when the API key already grants the deployment. Admin users have no rows inuser_deployments(their access is implicit by role), so the user-side check fails and the request is rejected even though the key explicitly grants write.The mirror bug is also there: a key with role
adminshort-circuits the function before the key's deployment cap is checked, so an admin-role key with a{my-app: write}scope silently gets access to every deployment.The fix is to treat the API key's deployment map as the authoritative scope when the underlying user has unbounded access (admin role), and to evaluate the key's cap even when the key's effective role is admin.