actualbudget/actual · error
forbidden
forbidden
Error message
forbidden: permission-not-found
What it means
The POST /openid (OpenID enable) endpoint is restricted to server administrators. If the authenticated session's user_id is not the owner/admin, the endpoint responds 403 with reason 'forbidden' and details 'permission-not-found'. This mirrors the permission model of other admin-only sync-server endpoints.
Source
Thrown at packages/sync-server/src/app-openid.ts:31
const app = express();
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(requestLoggerMiddleware);
const openIdConfigRateLimiter = rateLimit({
windowMs: 15 * 60 * 1000,
max: 5,
legacyHeaders: false,
standardHeaders: true,
message: { status: 'error', reason: 'too-many-requests' },
});
export { app as handlers, openIdConfigRateLimiter };
app.post('/enable', validateSessionMiddleware, async (req, res) => {
if (!isAdmin(res.locals.user_id)) {
res.status(403).send({
status: 'error',
reason: 'forbidden',
details: 'permission-not-found',
});
return;
}
const { error } = (await enableOpenID(req.body)) || {};
if (error) {
res.status(500).send({ status: 'error', reason: error });
return;
}
res.send({ status: 'ok' });
});
app.post('/disable', validateSessionMiddleware, async (req, res) => {
if (!isAdmin(res.locals.user_id)) {View on GitHub (pinned to d4334cb6e6)
Solutions
- Authenticate as the owner (first/bootstrapped) user of the sync-server
- Log in with the owner's credentials to obtain an admin session before calling POST /openid
- If you are the owner, verify the session user_id resolves as admin (it is the first user / role 'admin')
- Avoid exposing admin endpoints to non-admin clients
Example fix
null
Defensive patterns
Strategy: validation
Validate before calling
// ensure the session belongs to the owner before calling const session = await getOwnerSession(baseUrl, ownerPassword); // then use session cookie for POST /openid
Type guard
null
Try / catch
if (res.status === 403) {
throw new Error('admin (owner) session required to manage OpenID');
} Prevention
- Use the owner account for server administration endpoints
- Don't expose admin endpoints to regular-user clients
- Check which user your session cookie belongs to before admin calls
- In multi-user setups, document that only the first/owner user can change auth config
When it happens
Trigger: A logged-in non-admin user (any user_id other than the owner) calls POST /openid on the sync-server with a valid session.
Common situations: Multi-user sync-server setups where a non-owner tries to enable OpenID authentication; automated scripts authenticating as a regular user instead of the owner; calling the endpoint from a client whose session cookie belongs to the wrong account.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
AI-assisted analysis of actualbudget/actual@d4334cb6e6 (2026-08-29).
Data as JSON: /api/errors/39df165af5d19203.
Report an issue: GitHub.