Skip to main content
Version: 3.1

Security and Privacy

This chapter describes the security mechanisms the platform ships with, what the infrastructure operator is expected to provide, and the known limits.

Shared Responsibilities

Operaide runs as a containerized HTTP application. Some security concerns are handled by the platform itself; others are handled by the infrastructure operator (for example, a cloud provider, a managed-services partner, or an internal platform team running Operaide on-premises).

ConcernPlatform (Operaide)Operator (Infrastructure)
TLS terminationNo — speaks plain HTTP internallyYes — reverse proxy / load balancer
Volume and database-at-rest encryptionNoYes — disk, volume, or KMS-level
Application-layer credential hashingYes (SHA-256)
Authentication / SSO / MFADelegated to external identity provider
Role-based access controlYes
Tenant isolation (org, app instance, process)Yes
Workflow-level audit trailsYes
Infrastructure metrics, host-level logsYes
Backup and disaster recoveryYes
Network segmentation, firewalls, WAFYes

This split matters: when the question is "how is data encrypted at rest?", the answer has two parts — Operaide hashes sensitive credentials inside the application, and the infrastructure operator encrypts the underlying volumes.

Authentication and User Provisioning

Operaide supports three ways to sign in:

  • Email and password, handled by the platform's built-in accounts system. New accounts receive a verification email before they can sign in.
  • OpenID Connect (OIDC) is the recommended single-sign-on integration. Operaide works with any OIDC-compliant identity provider, including Microsoft Entra ID, Keycloak, Google Workspace, and Okta. Sign-in uses an OAuth 2.0 authorization-code flow with PKCE. Multi-factor authentication, conditional access, and session-related security signals are enforced by the provider. Operaide does not see or store the user's password. See SSO Setup for configuration.
  • Legacy Entra-specific integration predates the generic OIDC path. It is retained only for existing internal deployments and will be removed once they have migrated to OIDC. Do not enable it on new deployments.

Users are added to an organization in one of three ways:

  • Invitation. An organization member with the appropriate role (for example, MemberManager) invites a user by email. The invited user appears with status invited until they accept the invitation.
  • Email-domain auto-assignment. An organization administrator can configure an email-domain regex on the organization. When a new user self-registers with an email address that matches the regex, the user is automatically assigned to that organization. Auto-assigned users initially receive a roleUnverifiedUser global role and must confirm their registration through the verification email before gaining active access.
  • First-user bootstrap. In development and in controlled bootstrapping scenarios, a configuration setting (MAKE_FIRST_USER_ADMIN_REGEX) lets the very first user of a fresh deployment come up with the permission to become a platform administrator. This is meant for initial setup only.

For machine-to-machine access, Operaide issues API keys:

  • Generated with cryptographically secure random bytes.
  • Stored as SHA-256 hashes — the plain-text value is shown once at creation and cannot be retrieved afterwards, not even by administrators.
  • Scoped to an organization and revocable at any time from the admin console, without redeploying.
  • Usable in Authorization: Bearer, basic auth, header, or query-parameter form, depending on the client.

Sessions are token-based, with expiry and secure token storage on the server side.

Authorization

Every server-side method in Operaide enforces permission checks. There are no unprotected business-logic endpoints.

Roles are organized into two layers — see Roles and Rights for the full catalog:

  • Global roles: SuperAdmin, SystemAdmin, and internal developer roles that govern platform-wide configuration.
  • Organization roles: Member, MemberManager, AppManager, CredentialManager, ReportingManager and related roles that apply within a single tenant.

Three properties of the RBAC model are worth highlighting from a security standpoint:

Transitive hierarchy

Roles are hierarchical. A higher role implicitly grants the permissions of lower roles in the same hierarchy. This reduces configuration drift and the risk of permissions being accidentally forgotten when a role is renamed or extended.

Composite roles

Administrators can bundle fine-grained technical permissions into business-oriented composite roles (for example, "Legal Review" or "Finance Analyst") without changing source code. This lets you map the platform's permissions onto your own organizational structure from the admin UI.

"Can Become" activation pattern for privileged roles

Privileged administrator roles (such as SuperAdmin and SystemAdmin) are not permanently active on the user's session. A user with the permission to hold such a role must explicitly activate it via a toggle in the UI; otherwise they operate with their lower baseline role. This prevents accidental use of elevated privileges during day-to-day work and creates a clear boundary between "can administer" and "is currently administering".

Feature flags complement RBAC by letting you enable or disable specific capabilities per organization and per role — useful for phased rollouts and for disabling a feature organization-wide without touching code.

A specific and important separation: view vs. write access to credentials. App developers can see that a connection exists and read its non-secret configuration, but only the CredentialManager role can create, modify, or reveal credentials. Developers can build workflows that use connections without ever being able to extract the secrets they hold.

Tenant Isolation

Operaide is multi-tenant by default. Isolation is enforced at several layers, so a failure at one layer does not immediately expose data across tenants:

  • Organization scoping. Every persisted record is bound to an organization. Server methods filter queries by the caller's organization automatically; cross-organization access is not possible through normal application paths.
  • Workflow step isolation. Inside a Reaktor, each Aktor receives only the data for its specific step. There is no global shared state across steps, which limits how far a compromised or misbehaving step can reach.
  • App instance isolation. A single app can be deployed as multiple independent App Instances. Each instance has its own configuration, its own database, and its own vector store. Instances do not share storage, even when they run the same app code.
  • Process isolation. App instances run in their own processes, with Unix file-system permissions separating their on-disk data. The App ↔ Platform boundary is HTTP, which makes container-level isolation (for example, running each app in a dedicated container) a configuration choice rather than an architectural change.

For deeper detail on the multi-tenancy model, see Multi-Tenancy.

Controlled Data Flows

A core architectural property of Operaide is that there are no implicit external data flows. Every connection to an external system — an LLM provider, a CRM, a document store, an API — is represented as a first-class Connection object:

  • Connections are typed, registered by the app that needs them, and validated against a Zod schema at configuration time. A misconfigured connection is rejected before it can be used in a workflow.
  • Connections are organization-scoped. A connection configured in one tenant is not visible to another.
  • Credentials inside a connection are write-only for the CredentialManager role; workflows and developers reference connections by name but never see the raw secrets.
  • When an app is uninstalled, its connection types are removed. Connection instances (the configured credentials) are preserved and flagged in the UI — an administrator decides whether to keep them for a potential reinstall or delete them manually.

The consequence is simple: to find every external data flow in an Operaide deployment, you look at the list of configured connections plus the platform's own required audit service connection (see Monitoring and Reporting for what data that carries). There are no hidden environment-variable credentials, no hard-coded endpoints in workflow code, and no undocumented outbound channels.

See Connection Management for the operational details.

Encryption

In transit

Operaide itself speaks HTTP. TLS termination, certificate management, and HTTP-to-HTTPS redirection are the responsibility of the infrastructure operator — typically a reverse proxy such as nginx, Apache, Caddy, or a cloud load balancer placed in front of the Operaide container. This is a deliberate design choice: it lets operators use their existing TLS practices, certificate authorities, and renewal tooling without Operaide reinventing that layer.

tip

For bare-metal or VM deployments, provisioning scripts are available on request that set up Docker, a Caddy reverse proxy with automatic TLS certificates via Let's Encrypt, and a basic firewall configuration on a fresh Ubuntu/Debian server.

Outgoing calls to external services — LLM providers, knowledge bases, custom APIs — use TLS at the transport layer of the client used.

At rest

Two layers protect data at rest:

  • Infrastructure layer. Volume, database, and object-store encryption (for example, via disk encryption, a cloud KMS, or encrypted backups) is provided by the operator. This covers the bulk of persisted data: workflow history, user accounts, vector stores, app databases, execution logs.
  • Application layer. Operaide additionally hashes sensitive credentials inside the application itself. API keys are never stored in plain text. Cryptographic random bytes (32 bytes) are used for key generation. When credentials must be passed to a subprocess (for example, a helper tool), they are written to a temporary file with restrictive Unix permissions (0600) and deleted after use.

Audit Logging and Usage Tracking

Operaide distinguishes two logging levels, and it is important to understand the difference.

Automatic and always on: Usage tracking

Independently of any debug setting, Operaide automatically captures structured usage records for every workflow execution and every AI call:

  • Reaktor usage — start time, end time, duration, success/error status, the initiating user, the run ID, and the related organization.
  • Token usage — model, provider, input and output token counts, cost (when available), the initiating user, and the related organization.

These records are persisted on the Operaide instance and surface in the Monitoring & Reporting dashboard in three tabs (Token Usage, Other Metrics, Reaktor Usage), with CSV export for external analysis and compliance evidence. See Monitoring and Reporting.

In addition, each Operaide instance reports aggregated metrics to a central audit service — token totals per organization and model, active users, workflow execution counts, storage usage, platform version. The audit service does not receive prompt contents or workflow payloads; it is designed for capacity planning, billing, and cross-instance observability.

Optional and granular: Detail logging (debug mode)

For root-cause analysis and workflow development, Operaide can also record per-step detail logs — including inputs, outputs, and intermediate values — for a specific deployment. This debug mode is off by default, enabled per deployment, and limited in retention (currently 30 days).

Debug mode can be toggled in two ways:

  • Interactively from the admin UI.
  • Programmatically via REST:
    • PUT /api/v1/deployments/{id}/debug-mode — turn debug mode on or off.
    • DELETE /api/v1/deployments/{id}/logs — purge the detail logs of a deployment.

The programmatic interface is designed for incident-response and monitoring workflows: enable debug mode, reproduce an error, collect the logs, disable debug mode, and optionally purge the logs when the investigation is complete.

Credentials are automatically redacted before detail logs are persisted. Three detection layers run on every value on its way into the trace or the platform logger: a match against well-known credential field names (apiKey, password, token, authorization, …), a check for well-known token prefixes (sk-, operaide_, ghp_, eyJ for JWTs, …), and a per-substring Shannon-entropy check that catches credentials embedded in URLs and connection strings. Detected values are replaced with a marker that preserves length and detection reason, so the trace remains useful for debugging without exposing the secret. The same redaction is applied to responses from the Connection REST API, which returns markers instead of plain-text credentials for scripting and agent-driven workflows. See Logging and Debugging for implementation details.

Login and access audit

For users who sign in through an OpenID Connect provider, authentication events (successful and failed sign-ins, MFA challenges, anomalous locations, conditional access decisions) are produced by the provider and live in the provider's audit log. Ingest them into your SIEM or compliance tooling from there. Operaide itself records the resulting application-level login events but does not duplicate the identity provider's detail.

For users who sign in through the built-in email/password flow, the platform's own accounts system produces the corresponding records. For compliance-sensitive deployments, configure the infrastructure operator to ship these logs into your centralized logging stack.

Long-term archival

The 30-day retention of Operaide's detail logs is not designed as a compliance archive. If your compliance regime requires longer retention of audit data, the recommended pattern is to export usage data periodically (via the CSV export or the audit-service feed) and archive it using your organization's existing long-term storage — for example, write-once object storage with object-lock semantics configured by the infrastructure operator.

Secure Development Lifecycle

Every change to the Operaide platform goes through a defined pipeline before it can reach a production deployment:

  1. Work happens on isolated feature branches.
  2. Changes are reviewed by at least one other developer.
  3. Automated quality gates run on every push: unit tests, end-to-end tests, linting, formatting, and static type checking.
  4. Merges into the main branch only succeed once the pipeline is green.
  5. Container images are built and pushed to the registry through an automated workflow — there is no manual path from developer laptop to production.

No code reaches production without passing through these stages. The full change history is preserved in Git and tied to release versioning.

Input validation is a first-class concern: all inputs at system boundaries — REST endpoints, workflow parameters, connection configuration — are validated against typed schemas and rejected before they reach business logic. URLs accepted from external input are sanitized against common injection patterns. Outgoing HTTP calls bind credentials from the connection object rather than passing through arbitrary headers from the caller.

Known Limits

The sections above describe what the platform provides today. The following limits are intentionally called out so that administrators can plan around them:

  • Detail-log retention is a fixed 30 days. There is no per-deployment configuration for detail-log TTL yet. Long-term archival belongs at the infrastructure layer, as described above.
  • Credential redaction is not PII redaction. The secret detector described above reliably removes credentials (API keys, tokens, passwords) from detail logs, but it deliberately does not touch regular business content. Personal names, email addresses, document contents, and prompt text remain in the trace when debug mode is enabled. For workflows that process personal data under GDPR, treat debug mode as a tool for controlled, time-boxed investigations — not as a permanent setting.
  • The platform does not include built-in SOC or incident-response automation. Health-check endpoints (/health, /healthiness) are available for the infrastructure operator to integrate into their own monitoring and alerting stack.
  • The audit reporter currently sends aggregated metrics only. It is not a replacement for a per-event audit stream into a SIEM. If you need one, pipe the local reporting data or the detail logs into your SIEM through the infrastructure operator.