Security
How Admin as a Service protects connection details, customer databases, custom screens and the audit log.
This page describes the platform’s protections for administrators and security teams on the customer side. For an admin tool, the main risk is the access path to production databases, so most of the protections below focus on that path.
Connection details and secrets
Section titled “Connection details and secrets”- Envelope encryption: each connection configuration has its own data key and is encrypted with AES-256-GCM. The data key is in turn wrapped by a master key. If one record is exposed, the others are not.
- Connection details are decrypted only on the execution server, right before it opens the connection to the database.
- Sensitive values are never sent back to the browser. Passwords, client-certificate private keys and HTTP data source header values are not returned to the interface, not even masked. The interface only indicates that a password is set; certificates are shown only as a summary (name, expiry date).
- Secrets are write-only. Admins and owners cannot read them back either. To change a secret, overwrite it with a new value.
- Connection details are never written to logs.
Customer databases
Section titled “Customer databases”- Users never send SQL. The browser sends only the action name and parameters; the server looks up the published SQL itself.
- SQL is checked at publish time. Publishing is blocked when a non-
enumparam sits where a column or table name goes; when there are several statements without a declared transaction; when there are schema-changing statements (DROP,ALTER,TRUNCATE,GRANT) and the data source does not allow them; or when a Read-only action containsINSERT,UPDATEorDELETE. On MySQL, each action can contain only one statement. - Parameters are always sent separately from the SQL and never concatenated into it. Dynamic column names accept only values from a fixed
enumlist. - Read-only actions run inside a read-only transaction. As a result, the database itself rejects writes even if a layer above it fails.
- Time and lock limits: per-action timeouts, cancellation of statements that wait more than 3 seconds for a lock, and limits on rows and result size. See Limits.
- Connections are separated per environment: a
devconnection is never used to run inprod. - When testing an HTTP data source connection, the platform calls only allowed hosts. Internal addresses are blocked after DNS resolution, right before connecting. No action type calls HTTP data sources yet.
The most effective protection remains on the customer side: give Admin as a Service a database account with the least privilege possible. See Deployment.
Permission checks on every run
Section titled “Permission checks on every run”Every time an action runs, whether from the Run action page, a screen, a JS action or a job, the server checks the following conditions in order:
- The person has access to this environment.
- The action is enabled in this environment.
- The person has permission on the action (
openmode, or listed in the grants ofrestrictedmode). For a JS action, the JS action must be allowed to call the action and the original person must still have permission. - When called from a screen: the action is among those the view declares.
- The person’s IP is on the environment’s IP allowlist.
- The run is within the rate limit.
If any check fails, the run is denied and still recorded in the audit log.
Screens (views) and custom code
Section titled “Screens (views) and custom code”- Views run in an isolated (sandboxed) iframe on a separate origin, apart from the main application. A view cannot read the application’s session and cannot make its own network calls; all data goes through actions.
- Views run with the permissions of the person viewing them. Publishing a view grants no permissions. If the viewer lacks permission on an action, that part of the screen has no data, and the rest of the screen still renders.
- When a view is published, the server checks it again: a real type check, the list of allowed imports, and the publisher’s permissions on every action the view declares.
- Transformers and JS actions run in an isolated sandbox on the server with no network access. JS actions do not receive secrets, and every action they call goes through all the permission checks above.
Audit log
Section titled “Audit log”- Every run is recorded, including denied ones, along with every change to actions, permissions, environments, data sources, variables, secrets, views, jobs and schedules.
- The audit log is append-only. Entries cannot be edited or deleted.
- Returned data is not stored: the audit log and run history record the row count, not the content. Params with names containing
password,token,secret,api_key… have their values hidden. - Deleting a user or a project does not delete the related audit log or run history.
See Audit log.
Accounts and sessions
Section titled “Accounts and sessions”- There is no public sign-up; only owners can create accounts.
- Passwords must be at least 12 characters long.
- Changing a password signs out every other tab and device. When an owner resets a password or deletes a user, that person’s sessions are revoked immediately.
Isolation between customers
Section titled “Isolation between customers”- Each customer has a separate organization. Data, encryption keys and secrets are never shared with other customers.
- Database connections are kept separate per organization, data source and environment.
- Traffic from the execution server to the customer’s systems leaves from a fixed IP address dedicated to that deployment, so the firewall needs to allow exactly one address. See Deployment.
See also
Section titled “See also” Deployment A dedicated environment per customer, and what to prepare.
Access control Members, groups and per-action run permissions.