Security
User Allowlist
By default, any user who can send messages to your bot can create sessions. To restrict access to a specific set of users, populate security.allowedUserIds in your config:
"security": {
"allowedUserIds": ["123456789", "987654321"]
}Values are platform user IDs as strings. For Telegram, this is the numeric user ID. For Discord, it is the user snowflake.
When the list is non-empty, SecurityGuard.checkAccess() rejects any incoming message whose userId is not in the list. The user receives no response (the message is silently dropped). An empty list means all users are allowed — this is the default and is appropriate when your bot is in a private group that only you can access.
To find your user ID:
Telegram: Message
@userinfobotor@getidsbot.Discord: Enable Developer Mode in Settings, then right-click your username and select "Copy User ID".
Concurrent Session Limits
"security": {
"maxConcurrentSessions": 20
}This is a hard cap on the number of sessions with status active or initializing across all channels at any given moment. When the limit is reached, new incoming messages are rejected with a "Session limit reached" response until an existing session completes.
The default of 20 is generous for personal use. Reduce it if you are on a machine with limited resources or want to prevent accidental runaway usage.
Session Timeout
Sessions that have been idle (no new prompt sent) for longer than this value are eligible for automatic cleanup. The default is 60 minutes.
API Authentication
The REST API uses a two-tier authentication system:
Secret token (master key)
The API secret is stored in <instance-root>/api-secret (default: ~/.openacp/api-secret). This file is created automatically on first start with 0600 permissions. The token is a 64-character hex string generated with crypto.randomBytes(32).
The secret token provides full administrative access. Use it for:
CLI-to-daemon communication (handled automatically).
Issuing JWT access tokens for apps and integrations.
At startup, if the file permissions are more permissive than 0600, a warning is logged:
JWT access tokens
For app clients and remote access, OpenACP issues scoped JWT tokens. Unlike the secret token, JWTs are:
Scoped — assigned a role (
admin,operator, orviewer) with predefined permissions.Revokable — can be revoked individually via the API.
Time-limited — expire after a configurable period, with a 7-day refresh window.
Stateful — tracked in
<instance-root>/tokens.jsonwith last-used timestamps.
Roles
admin
Full access: manage sessions, config, agents, tokens
operator
Create/manage sessions, send prompts, view config
viewer
Read-only: view sessions, status, and events
Issuing tokens
Tokens are issued by authenticating with the secret token:
Or use openacp remote to generate a one-time access code that can be exchanged for a JWT (see App Connectivity).
Revoking tokens
Network security
Do not expose the API port externally. The default host: "127.0.0.1" binding ensures the API is only reachable from localhost. If you change api.host to 0.0.0.0, the server logs a warning — ensure your firewall blocks external access to port 21420.
For remote access, use a tunnel instead of exposing the port directly. The tunnel provides HTTPS encryption and access control via one-time codes.
Bypass Permissions
Some agent operations (file writes, command execution) require explicit user approval via permission request buttons in the chat. This is the default behavior. For details on how permissions work from a user's perspective, see Permissions.
If an agent is configured to run without permission prompts (agent-side configuration), ensure your allowlist is restricted to trusted users only, since any allowlisted user will have the ability to trigger unrestricted agent actions.
Best Practices
Always set
allowedUserIdsunless your bot is already in a fully private, access-controlled group. Even a private Telegram group can have its invite link shared accidentally.Keep
api-secretat0600. The CLI warns you if it is not. Runchmod 600 ~/.openacp/api-secretif needed.Do not change
api.hostto0.0.0.0unless you have a specific need and have locked down port21420with firewall rules. Use tunnels for remote access instead.Review
maxConcurrentSessionsif you share the bot with multiple users. A session per user is reasonable; 20 concurrent ACP agent subprocesses can be resource-intensive.Rotate the API secret by deleting
~/.openacp/api-secretand restarting the daemon. A new token is generated automatically. All existing JWT tokens issued from the old secret become invalid.Use daemon mode with autostart for persistent deployments so the server does not silently go offline after a reboot.
Revoke unused JWT tokens periodically. Use
GET /api/v1/auth/tokensto list active tokens and their last-used timestamps. Revoke any you no longer need.
Last updated
Was this helpful?
