FreeScout's API & Webhooks module has one API key for the whole instance. Every connected application shares it, it can do everything (including creating and deleting users), and one click of the Regenerate button replaces it instantly, with no confirmation — breaking every application at once.
This module adds proper key management on top, without touching the API & Webhooks module's code:
- A key per application, each with its own name and description.
- Scopes — a key can only call the endpoints you tick, and can be limited to chosen mailboxes.
- Safe rotation — regenerating a key can keep the old one working for a grace period (1 hour to 7 days), so the application is updated with no downtime.
- Revoke and restore — kill one key without touching the others; undo a mistaken revoke with one click.
- A guard on the master key — regenerating it now needs a typed confirmation, enforced on the server.
- Last used time and IP per key, so dead keys are easy to spot.
- An audit trail — who created, changed, revoked or regenerated what, and when.
- Optional expiry dates and IP allowlists per key.
Keys made by this module keep working even if the master key is regenerated.
Everything lives on one page: the master key guard, the new key form, and the activity log.
Keys look like fskey_... and are checked before the normal API auth runs.
A valid key is swapped for the master key on the way in, so the
API & Webhooks module behaves exactly as normal. Only a SHA-256 hash of each
key is stored — a key is shown once, at creation, and never again.
The master key itself still works, unchanged. Nothing breaks when this module is installed; move applications over to their own keys at your own pace.
- FreeScout 1.8.198 or newer.
- The API & Webhooks module, installed and active.
- Copy the
ApiKeyManagerfolder into FreeScout'sModulesdirectory. - Give it the same file ownership and permissions as your other modules.
- Activate API Key Manager on the Modules page.
- Create the module's database tables: go to Manage » System and press
Migrate DB (or run
php artisan migrate --force). Activation alone does not do this — until it is done, the settings page shows a notice asking for this step. - Open Manage » Settings » API Keys.
Create a key: name it after the application, tick its scopes (the preset buttons cover common cases), optionally limit it to mailboxes, then copy the key from the yellow box — it is shown only once.
Rotate a key: type the key name in the Confirm field, pick how long the old key should keep working, and press Regenerate. Update the application with the new key any time inside that window. Press "Stop old key now" once done, or let the window lapse.
Revoke a key: type the key name in the Confirm field and press Revoke. It stops working immediately. Restore brings the same key back; Delete removes a revoked key for good (its audit history is kept).
Each key lists as a row and opens into its own panel. Only the key's prefix is ever shown, because only a hash of the full key is stored. Regenerate, Revoke and Delete stay inert until the key's name is typed into the Confirm field.
The master key guard: with the guard on, the Regenerate button on the API & Webhooks page asks for a typed confirmation first. The server refuses unconfirmed regenerations as well, so this is not only a dialog.
The high risk scopes — creating/deleting users and managing webhooks — are not included in any preset. Tick them only for an application that truly needs them.
- Mailbox limits do not cover customers, users or tags — those are shared across FreeScout, not tied to a mailbox. Use scopes to control them.
- Scope denials return a plain 403 with no detail (that is all the API & Webhooks module's hook allows). The reason is written to the FreeScout log.
- New API endpoints added by future API & Webhooks versions are refused to scoped keys until this module maps them — deliberately, so an old key is never silently granted new powers. The refusal is logged.
- IP allowlists need real client IPs. Behind a proxy, confirm FreeScout sees the caller's IP (not the proxy's) before relying on this.
- The master key still exists and still has full access. Treat it as break-glass: keep it somewhere safe and give applications their own keys.
Set APIKEYMANAGER_DISABLED=true in FreeScout's .env file to switch the
module off without uninstalling it. Keys made by this module stop working;
the master key keeps working. Deactivating the module on the Modules page has
the same effect.
php artisan apikeymanager:expiring --days=14
Lists keys that are expired or expiring within the given number of days. Suitable for a cron job.
Bugs and questions: open an issue.
Security holes: please do not use a public issue. See SECURITY.md for the private reporting link.
AGPL-3.0, the same as FreeScout. See LICENSE.


