fepli
DevelopersREST API

Service accounts

A service account is an identity for a machine rather than a person: an integration, a reporting job, an AI support agent. It has its own roles, it keeps working when colleagues leave, and it can be capped at read-only no matter which tokens are created for it.

Why not a personal token?

A personal access token acts as the colleague who created it. That's fine for trying things out, but not for something that keeps running:

  • When the colleague leaves or loses a role, the integration stops working, or it quietly gains access when they are promoted.
  • Everything the integration does is logged as the colleague's own work.
  • You can't give the integration less than the colleague has.

A service account fixes all three. It has exactly the roles you give it, nothing it does is attributed to a colleague, and its access level decides once and for all whether any of its tokens may write.

A service account signs in with API tokens only. It has no password and can't open the admin.

Create a service account

Service accounts are managed by super admins:

  1. In the admin, open Einstellungen → Integrationen → API and choose Service-Accounts verwalten.
  2. Choose Neuer Service-Account and fill in:
    • Name: how admins recognise it, for example "Support-Agent". The name appears in logs and on comments the account writes.
    • Beschreibung: what the account is for and who is responsible for it.
    • Zugriff: Nur lesen or Lesen und schreiben. See Access level.
    • Rollen: which sections of the admin the account can see. See Roles.
  3. On the account's page, create a token under Tokens. Give it a label, choose its Zugriff, and set an expiry date. Lesen und schreiben is only offered when the account's own access level allows writing, and a disabled account can't get new tokens.
  4. Copy the token. It starts with svc- and is shown this one time only.

Roles

A service account gets the same roles as a colleague. They decide which endpoints it can use (see Permissions):

RoleAdmin labelUnlocks
ROLE_ADMINAdminoffers, editions, hosts, attendances, accounts, consents, comments, sent messages, search
ROLE_PARTICIPANTS_ADMINTeilnehmer:innenparticipants, and the names of an account's participants; only together with Admin
ROLE_PAYMENTS_ADMINZahlungenreceipts, debtors, and an account's debtor; only together with Admin
ROLE_SUPER_ADMINSuper-Admineverything: includes Admin, Teilnehmer:innen and Zahlungen, plus creating admin accounts and changing admin roles
ROLE_HOSTVeranstalter:inneneditions and offer categories only, see below

A new service account gets the role Admin and the access level Nur lesen. Add Teilnehmer:innen or Zahlungen only when its job needs participants or payments: every role opens more personal data to its tokens. Both count only together with Admin or Super-Admin, and the admin won't save them without one of the two.

Host users see the offers of the hosts they are members of. A service account is not a member of any host, so with Veranstalter:innen alone it sees no offers and no hosts. The same goes for any service account without Admin: even the published offers only come back without a token. Give it Admin if it needs offers.

A service account always belongs to exactly one tenant. The global admin role of multi-tenant installations can't be given to it.

Access level

The access level is the ceiling for every token the account holds:

  • read (Nur lesen): every token of the account can only read, even one that was created with write access before the account was restricted. A read-only service account can't change anything, but it reads everything its roles allow.
  • write (Lesen und schreiben): tokens can read and, if they were created with write access, also write.

Changing the access level takes effect on the next request of every token.

Create one from the command line

On the server, ferienpass:api:service-account creates a service account and its first token in one go. That's useful for provisioning an integration without a browser, or for a new tenant where no super admin has signed in yet.

A read-only reporting job with one role and an expiring token

bin/console ferienpass:api:service-account "Auswertung" --tenant=elmsbrueck \
  --role=ROLE_ADMIN --valid-until="+90 days" \
  --description="Monthly report on attendances"

A read-only account that also reads participants

bin/console ferienpass:api:service-account "Statistik" --tenant=elmsbrueck \
  --role=admin --role=participants_admin
  • Name
    name
    Type
    argument
    Description

    A name admins recognise the account by. Required.

  • Name
    --tenant
    Type
    string
    Description

    The tenant (its slug). Required on multi-tenant installations; run ferienpass:tenant:list to see them.

  • Name
    --access
    Type
    string
    Description

    read (default) or write.

  • Name
    --role
    Type
    string
    Description

    A role to grant, repeatable. Accepts ROLE_ADMIN or just admin. Defaults to ROLE_ADMIN. participants_admin and payments_admin need admin next to them; the command refuses them otherwise.

  • Name
    --description
    Type
    string
    Description

    What the account is for.

  • Name
    --token-name
    Type
    string
    Description

    A label for the first token.

  • Name
    --valid-until
    Type
    string
    Description

    Expiry of the first token, as a date (2027-01-01) or relative (+90 days). Without it, the token doesn't expire.

  • Name
    --no-token
    Type
    flag
    Description

    Create the account only, and create tokens in the admin later.

The command prints the token once. Store it like a password.

Manage tokens

A service account can hold several tokens, for example one per environment. On the account's page you see when each token was last used (to within five minutes), and you can:

  • Revoke a token. It stops working immediately. Do this when a token is no longer needed or may have leaked, and to rotate a token: create the new one, switch the integration over, then revoke the old one.
  • Disable the account. All its tokens are refused with 401 (Service account disabled) until you enable it again. Use this to pause an integration without losing its setup.
  • Delete the account. Deletes it together with all its tokens.

End-to-end encryption

Where a tenant encrypts the personal data of its participants end to end, a service account sees their names only as pseudonyms until it holds a key of its own. The integration makes the key itself and registers it; a super admin confirms it in an emoji comparison and decides what it reads: every participant, or the children of one host. See End-to-end encryption.

On the service account's page, super admins find the key under Verschlüsselung: whether there is none, one waiting or one confirmed, its fingerprint and key ID, what it reads and who confirmed it. Schlüssel widerrufen takes it back at once, and deleting the service account does so too.

What a service account leaves behind

fepli names a service account where a record keeps a name as text. Records that point to a person's account don't name it:

  • Comments it writes show its name as authorName.
  • Consents it revokes show its name as revokedBy.
  • Host invitations it sends name it in the e-mail; their invitedBy is null. While an edition asks hosts to sign a confidentiality declaration, it can't invite anyone to register a new host for that edition (409): a service account can't sign.
  • Receipts it records have no recordedBy, because that field points to a person's account. Their recordedByName reads {name} (Service-Account).
  • Changes it makes to attendances appear in the attendance's history in the admin as {name} (Service-Account). Attendances it creates count as entered by the team (createdByAdmin).
  • Offer workflow transitions it applies (publish, cancel, …) appear in the offer's history in the admin as {name} (Service-Account).
  • Each of these keeps the name the service account had at the time.
  • Nobody gets the e-mails about the participant list of offers it creates; who gets them is chosen in the admin, under Listen-Empfänger:innen. Like every new offer, they take their contact from the first host's profile unless you send contact (Create an offer).

Was this page helpful?