Security

Erlangly is self-hosted: it runs on your server, so your data never passes through ours.

Approving Erlangly for your organization? For your IT and security team covers how it runs, what connects where, encryption, backups and access, with the usual security questionnaire filled in.

In short

  • Your server, your data. Nothing passes through ours, and there's no telemetry.
  • Strong sign-in. Long passwords, two-factor authentication for admins, and single sign-on.
  • Least access. Tokens, integrations and AI assistants can do only what they're given, and clients' data is kept apart.
  • A full record. An append-only audit trail of who changed what.
  • Admins are told. Sensitive changes are emailed to the people they affect.

Setting up

  • A new install is set up through a secret one-time link, so nobody else can claim it.
  • It's then activated with a license (the free plan, a trial or a key) before anything else opens.

Passwords

  • Hashed with bcrypt, at least 12 characters. Password sessions last 30 days.
  • Each account gets 10 sign-in tries in 3 minutes from any one network, and 100 across all networks. A password can't be guessed by trying many, someone elsewhere can't keep a person shut out without many separate networks, and a whole floor can still sign in at once from one office address.
  • A password reset assumes someone else may have had the old one: it signs the person out everywhere and revokes their API tokens and AI assistants.
  • Changing a password signs them out everywhere else, and revokes those too if they ask.
  • Either way, once email is set up, they're emailed about it.

Two-factor authentication

  • Admins who sign in with a password use it: a code from an authenticator app (TOTP), or one of 10 single-use recovery codes (16 characters, a–z and 2–7, 80 bits). An organization can ask it of everyone with a password.
  • Each person gets 10 tries at a code an hour, and each code works once. Wrong codes after a right password are in the audit trail, and using up the tries is emailed.
  • Setting it up asks for the password before it shows a key. Moving it or turning it off asks for the password and a code. Each change is emailed.
  • A device can be remembered for up to 90 days (30 to start with, or never), so it asks for the password alone, with a new token each time. A new password forgets them all.
  • Asking less of people in Settings takes the admin's own code if they use two-factor authentication, and the other admins are emailed.
  • Only an admin who types their own app's code, or the server, resets someone's two-factor authentication. That also revokes their API tokens and AI assistants.
  • Showing someone's password reset link is in the audit trail, and changing their email address emails the old one.

Single sign-on

  • Single sign-on uses OpenID Connect with PKCE. Erlangly checks the provider's signature on every sign-in itself, against the provider's published keys.
  • Only people you've invited, with an email address in the domains you allow, can sign in; with Microsoft, only members of your organization.
  • SSO sessions last 12 hours, so someone turned off at the provider can't sign in again after that shift. Turn them off in Erlangly too to end their API tokens and AI assistants at once.
  • When SSO is required, break-glass admins keep a password and two-factor authentication. Once email is set up, each of their password sign-ins is emailed to the other admins.

API and integration tokens

  • API tokens are stored only as digests and shown once. Making one takes its owner's two-factor code, or else their password, unless they must sign in with SSO. Each acts with its owner's role and sees only the clients its owner sees.
  • Integration tokens, for your own systems (an HR sync, a payroll export), are stored and shown the same way. Each acts as an integration's own user, which can't sign in, with the clients an admin chose.
  • An integration token can use only the endpoints its abilities open; anything else is refused, reading included. Besides reading, an admin can let one import people, time off and balances from your HR system and send back HR's ID for leave approved in Erlangly. It can never ask for or decide time off, or publish.
  • Making or changing one takes the admin's password again (with their authenticator code if they use two-factor authentication) or a fresh sign-in at the identity provider, within the last 10 minutes. Every admin is emailed.
  • They expire within a year, have their own limit of 600 requests a minute, and can't be used by AI assistants.

Imports from an HR system

  • Over the API or with the erlangly command on the server, imports keep only the columns Erlangly reads, so pay or home addresses in an export are dropped before it's saved.
  • Their files are cleared a week after they came. Once they can't be undone, 30 days after, the names, dates, balances and notes of their rows are cleared too.
  • A people import needs a token that sees all clients.
  • In case the export went wrong, an import is refused unless it's sent again with force when it would affect more than a tenth of the floor (and at least 10 people): making them leave, leave earlier than recorded, or come off a line they're scheduled on within a day.
  • AI assistants can't import.

Webhooks

  • An admin adds them under Settings → Integrations, after confirming who they are as for an integration token. Every admin is emailed when one is added, changed or removed, or turned off after 3 days of failing.
  • They post thin events (what changed, with IDs and dates, never names or notes), signed with HMAC-SHA256 as Standard Webhooks are.
  • Their secrets are encrypted at rest and shown once; a new one keeps the old signing for 24 hours.
  • Erlangly connects only to public addresses over https. It looks the name up as it sends and connects to the address it checked, follows no redirects, waits 10 seconds for an answer and keeps only its status code.
  • Never the server's or its container's own addresses, loopback, link-local or the cloud metadata service. Private addresses only in ranges the server's operator allows with erlangly webhooks allow, on the server, never from Erlangly, and that's in the audit trail. See Webhooks.

Keeping clients apart

  • On an install that serves several clients, admins can limit planners and supervisors to the clients they work for.
  • Each client's data is then kept from the others' staff on every page, download and import, and through the API and AI assistants. Another client's records answer as if there were none. But someone who works for two clients is seen by both clients' staff, with their time off and exceptions, and that person's shifts for the other client, and overtime worked for it outside a shift, name that client and its line of business, including through the API and AI assistants.

Audit trail and exports

  • An append-only audit trail records who created, changed or removed people, users, time off, shifts, breaks, schedules, forecasts and settings, and every export, with the API token or AI assistant a change came through.
  • What was removed is kept in it as it was, with the reason when one was asked for.
  • Shifts generated, imported or removed with their schedule aren't in it one by one, and an import from an HR system is one line, naming the integration or person and how many records it changed.
  • Admins read it in Settings → Audit trail, and export all of it.
  • Exports (Settings → Export, admins only) leave out passwords, tokens, the license key and the mail and sign-in secrets, and are deleted after a week.
  • The mail server password is encrypted at rest and kept out of the audit trail.

On the server

  • A strict Content-Security-Policy, and HTTPS with a Let's Encrypt certificate when you give it a domain.
  • Request bodies are limited before anything reads them: 10 MB at the proxy, and 2 MB for JSON and the API.
  • The container runs as an unprivileged user.
  • Nightly backups stay on your server; copies elsewhere are up to you.

What leaves your server

  • No telemetry. The server's only call to us is a daily update check, which you can turn off.
  • Activating the license goes through an admin's browser instead, once. It sends the key's id, a random id for the install and the install's address to store.erlangly.com, and brings back a signed code the server checks offline.
  • Notifications to phones and computers travel encrypted through the push service of each person's browser (Apple's, Google's, Mozilla's or Microsoft's), which can't read them, and nothing reaches us. A lock screen shows only what happened, with the person's own dates, times and activities and a colleague's first name. An admin can turn them off for everyone. See What connects where.

AI assistants

  • They can only connect (over MCP) once an admin turns it on.
  • Each acts as the person who signed it in (OAuth 2.1 with PKCE, or a personal token for developer tools): read-only unless they chose otherwise, and never able to publish a schedule.
  • Signed in with OAuth, an assistant's keys expire within the hour and it never sees other people's personal details.
  • People see and disconnect their own; admins see and disconnect everyone's.

Reporting a problem

If you find a security problem, please email security@erlangly.com with what you found and how to reproduce it. We'll reply within two business days, keep you posted while we fix it, and credit you if you'd like. Please don't test against installs that aren't yours.