1. Principles
- Unique identity. Every person and every system has its own credential. Shared accounts are not allowed, except the server
rootaccount described in section 5, which is used only by the Founder and is scheduled to be replaced. - Least privilege. Access is granted for a need, at the lowest role that meets it, and removed when the need ends.
- Strong authentication. Multi-factor authentication (MFA) is mandatory for every platform user and required on every supplier account that can reach customer data or production.
- Deny by default. A request without a valid identity, role or organization context is refused.
2. Platform users (in place)
- No public sign-up. Organizations and their first user are created only by the operator (
sw:criar-organizacaoor the vendor review screen), both through the same provisioning service; each creation is written to the audit log. - Temporary password. A new user receives a unique temporary password that expires in 72 hours and must be changed at first login.
- Password rules. Minimum 12 characters with upper case, lower case and numbers; stored only as a bcrypt hash.
- MFA for everyone. TOTP (RFC 6238) is mandatory and cannot be turned off; codes cannot be replayed; 8 single-use recovery codes are issued. The TOTP secret and recovery codes are encrypted in the database (policy 02).
- Step-up for critical actions. Approving a critical AI-agent action asks for a fresh MFA code even with an open session.
- Brute-force limits. Login and MFA attempts are rate-limited (5 attempts), and failures and lockouts are audited.
- Sessions. Session data is stored server-side in the database and encrypted. The reference configuration from which the production file is created sets the session cookie HTTPS-only, HTTP-only and SameSite=strict, with a 60-minute idle timeout. Commitment: confirm these values on the production server and record the evidence (owner: Founder, target 2026-10-15).
- MFA reset. Only the operator can reset a user's MFA (
sw:mfa-redefinir), which also ends that user's sessions and is audited. The operator confirms the request with the organization's owner through a known channel before resetting.
3. Roles inside a customer organization (in place)
| Role | Can do |
|---|---|
| Owner | Everything in the organization, including members and settings |
| Admin | Configure agents, tools, policies and keys; cannot approve agent actions by default |
| Approver | Approve or deny agent actions; cannot change policies |
| Analyst | Work on cases and read decisions |
| Viewer | Read only |
Permissions are checked on every request. Every tenant query is scoped to the current organization and throws an error instead of returning data when no organization is set; this is covered by automated tenant-isolation tests.
Platform reviewers (is_platform_admin) can review vendors but never a vendor they are linked to.
4. API keys (in place)
- Keys are issued per environment: an organization may hold several keys for the same environment, and each key is bound to exactly one organization and one environment. Each key has 40 random characters, is shown once and is stored only as a SHA-256 hash.
- Keys can be revoked at any time by the customer; creation and revocation are audited.
- Each key is rate-limited and can only act inside its own organization and environment.
5. Privileged and server access
In place today (verified on the server):
- SSH login is by key only; password authentication is disabled;
rootcan log in with a key only. - fail2ban protects SSH; the ufw firewall allows only ports 22, 80 and 443.
- The application connects to PostgreSQL with its own database role, limited to its own database.
- Code is pulled on the server with a dedicated, read-only GitHub deploy key.
In rollout: separate database roles so that the application role cannot alter or disable the append-only audit table (owner: Founder, target 2026-10-15).
Commitments:
- Create a named administrator account with
sudoand disable directrootlogin over SSH (owner: Founder, target 2026-11-30). - Move SemantiqWall to its own PHP-FPM pool and system user, and then to a dedicated server; today the VPS also hosts other projects of the Founder (owner: Founder, target 2026-12-31).
- Prefer hardware-backed SSH keys (FIDO2,
ed25519-sk) for administration (owner: Founder, target 2027-03-31).
6. Supplier and tool accounts
The Founder's accounts at GitHub, Hostinger (VPS panel), Resend, GoDaddy (Titan mailbox and domain registrar) and any AI provider must have MFA enabled and a unique password stored in a password manager.
Status: to be verified. Commitment: confirm MFA on each account, record the evidence in the security register (owner: Founder, target 2026-10-15).
7. Provisioning and de-provisioning
- Customer users: created by the operator when an organization is created or, inside an organization, by its owner or an administrator with Add member on the Organization page (there is no e-mail invitation). An e-mail that already has an account only gains the membership and keeps its own password and MFA. A new account gets a random temporary password, shown once on screen to the person who added it (never logged, never in the audit log, no e-mail sent); it expires after 72 hours, must be changed at first sign-in, and MFA setup is enforced before the panel opens. Administrators cannot grant the owner role. Each addition is recorded in the audit log.
- Member removal (in place): owners and administrators remove a member from the Organization page. Access to that organization ends at once; when the person belongs to no other organization, their sessions are ended and "remember me" is invalidated. An administrator cannot remove an owner, the last owner cannot be removed, and nobody removes themselves. Each removal is recorded in the audit log.
- Platform reviewers: added and removed with
sw:revisor(--remover). - Staff (from the first hire): access is requested and approved in writing by the Founder, granted at the lowest role, and removed on the last working day at the latest - server keys, repository access, supplier accounts and platform accounts - with the removal recorded in the register.
8. Access reviews
Starting in Q4 2026 and then every quarter, the Founder reviews and records in the register:
- server
authorized_keysand system accounts; - GitHub collaborators, deploy keys and GitHub App installations;
- platform reviewers and platform organizations' owners;
- supplier accounts listed in policy 09.
Anything not justified is removed. First review: owner Founder, target 2026-10-31.
Customers are responsible for reviewing their own members and API keys (policy 11).
9. Secrets
- Secrets (APP_KEY, database password, API tokens of suppliers) live only in the server
.envfile with restricted permissions, in files referenced by path (the GitHub App private key), or in the root-only (0600) files listed in policy 02: the database owner credentials in/etc/semantiqwall/db-owner.envand the.envcopy made during the database-roles rollout. They are never committed to the repository and never written to the audit log. - Secrets are generated with a cryptographically secure generator (policy 02).
- Rotation and revocation follow policy 02.