← Back to Wiki
Self-Hosting / Security

Use Dedicated Service Accounts for Automation, Not Your Admin Login

You want a script to post a deploy notification, a status update or a moderation action into some self-hosted app. The lazy path is reusing your own login. It already works, and it is one less thing to set up. It is also the wrong call the moment that credential lands in a config file, a cron job or a CI pipeline. Here is the pattern that avoids it, using a real self-hosted chat app's bot accounts as the example, plus the lessons that apply whatever you are automating.

Share on X

Why not just reuse your own login

Three concrete problems, not just a vague "best practice":

The pattern: a real account, not a special auth mode

The self-hosted apps that get this right do not invent a separate bolt-on auth system for automation. They give it a real account in the existing user and permission model, authenticated differently. Outpost, a self-hosted Discord alternative, is a clean example. Its API bot accounts are real members with real roles. The only difference from a human member is that they authenticate with a long-lived token instead of a password, over the same REST and gateway API any client uses. No parallel bot-only API surface to maintain. No special-cased permission model to reason about separately.

That is the shape to look for. Or to build, if you are the one adding automation support to something:

  1. A real account row in the existing user table, flagged as a service or bot account rather than modeled as something entirely separate.
  2. Normal role and permission assignment, the same system a human account uses. A script gets scoped to exactly what it needs, like posting in one channel rather than managing the whole instance, with no second permission system to audit.
  3. A token issued once and shown once, not a reusable password. If the app cannot show you the credential again after creation, it is probably not storing it anywhere retrievable either. That is the property you want.
  4. Independent revoke and delete. Killing the automation's access should not require touching any human account's credentials.

Grant the narrowest role, not the convenient one

It is tempting to hand a new automation account an admin or owner-equivalent role so you never think about it again. Do not. The blast-radius point above applies to the role you grant, not just the account you grant it to. A deploy-notification bot needs permission to post in one channel. Full stop. Work out the real minimum before you wire in the credential, not after something goes wrong.

BE WARNED, found while setting up a self-hosted password manager to store one of these tokens. Vaultwarden's CLI silently drops the password field if the created item lands in a shared organization collection. That is bw create item with item type 1, a login. It saves the username and everything else. Just not the secret you needed stored. The same call works correctly as a personal, non-org item. If a freshly created login item in your vault is missing its password with no error anywhere, check whether it landed in a shared collection before you blame the credential. It is very easy to lose ten minutes suspecting the wrong thing. The password manager guide has the base Vaultwarden setup this applies to.

Where the token actually lives

Once you have a scoped, independently revocable credential, treat it like any other secret. A password manager entry, as a personal item per the warning above, or your CI system's own secret store. Never committed to a repo. Never pasted into a chat message or an issue thread to "share it with the team". If the automation runs somewhere with standing SSH access, a plain environment file readable only by the service's own user is a reasonable fallback. A real secret store beats that whenever one is available.

The checklist

  1. Does the app support a real dedicated account type for automation, separate from your own login? If not, that is a gap worth weighing against the alternatives.
  2. Grant it the narrowest role the automation needs. Work that out before you wire in the credential.
  3. Store the token in a real secret store, as its own entry. Not bundled into a shared or org collection, where a tool's quirks can silently drop part of it. See the Vaultwarden warning above.
  4. Confirm you can revoke just this credential later without touching any human account.