Security Guide
Purpose and Audience
This guide is written for security administrators, CISOs, and platform/infrastructure owners who are evaluating, deploying, or operating SWIRL Enterprise. It describes SWIRL's security posture, the controls SWIRL provides out of the box, the controls customers are responsible for, and how to harden a production deployment.
For day-to-day administration, see the Admin Guide. For deployment topology, see the Installation Guide, the Kubernetes Deployment Guide, and the Monitoring Guide.
Security Model at a Glance
SWIRL Enterprise is deployed inside the customer's own environment — in a private VPC, on-premises, or in a customer-controlled cloud tenant. SWIRL does not run as a multi-tenant cloud service, and SWIRL Corporation has no access to customer data, user identities, or query logs unless the customer explicitly shares them for support purposes.
Key properties a CISO should understand before anything else:
- No data ingestion, copying, or indexing. SWIRL is a federated metasearch engine. Queries are dispatched to authorized source systems at request time, and results are re-ranked in memory. SWIRL does not build a persistent index of source content.
- User identity and entitlement remain with the source systems. A user only sees results from data they are already authorized to access in the underlying source. SWIRL brokers the request; it does not replicate or store source documents.
- External AI providers are customer-selected. All LLM endpoints used for query rewriting, RAG, and chat are configured by the customer via the
AIProviderobject. SWIRL never sends traffic to a hardcoded third-party LLM. - Runs in the customer trust boundary. SWIRL ships as container images (Docker Compose or Kubernetes) that the customer deploys into infrastructure under their own IAM, network, and key-management controls.
Shared Responsibility
| Area | SWIRL Provides | Customer Owns |
|---|---|---|
| Application code & container images | Signed, versioned releases; CVE hygiene in dependencies | Image pull policy, registry access control, patch cadence |
| Authentication | Pluggable OIDC/OAuth2, Django auth, login throttling (django-axes) | IdP configuration, MFA enforcement, password policy |
| Authorization | User and Group model, per-object permissions, group-scoped SearchProviders | Role design, group membership, group-to-source mapping |
| Transport security | Support for TLS termination at a reverse proxy; X-Forwarded-Proto honored |
Certificate issuance, cipher policy, HSTS at the proxy |
| Data at rest | Uses the backing PostgreSQL/Redis you configure | Disk/volume encryption, DB encryption, Redis auth |
| Secrets | Reads all secrets from environment variables; no secrets in code | Secret storage (Kubernetes Secrets, Vault, KMS, etc.) |
| Source credentials | Per-SearchProvider credential field; per-user OAuth tokens for M365/Google/Box |
Rotation, scope minimization, least-privilege service accounts |
| Logging | Application, Celery, and authentication logs to stdout/files | Log aggregation, retention, SIEM ingestion |
| Network controls | Documented egress targets | Firewall rules, network policies, WAF, egress filtering |
| Backups / DR | Backup-agnostic (Postgres dump compatible) | Backup schedule, off-site copies, restore drills |
Identity, Authentication, and Session Management
Supported Authentication Methods
SWIRL Enterprise supports multiple authentication methods simultaneously so that interactive users, integrations, and administrators can use the appropriate flow:
- Single Sign-On via OAuth2 / OpenID Connect (OIDC) with PKCE for public clients. SWIRL has been deployed with PingFederate, Microsoft Entra ID (Azure AD), Okta, Auth0, and Google, and will work with any standards-compliant OIDC Identity Provider. Auto-provisioning of Django users from OIDC claims is supported. See Connecting to Other Authentication Systems.
- Per-source OAuth2 for Microsoft 365 (Outlook, OneDrive, SharePoint, Teams, Calendar) and Google Workspace. User tokens are scoped to the connected source and stored per user. See the Microsoft 365 Guide and Google Workspace Guide.
- Session authentication for the Galaxy UI after SSO login.
- Token authentication (DRF tokens) and HTTP Basic authentication for API clients and automation. Token-scoped calls are the recommended pattern for integration accounts.
SAML is not natively built in; customers requiring SAML typically front SWIRL with an IdP that exposes OIDC, or place SWIRL behind a SAML-aware reverse proxy.
Brute-Force Protection and Lockout
SWIRL ships with django-axes enabled by default. Failed login attempts are tracked, and repeated failures lock the account:
- Default failure limit: 4 attempts before lockout (
AXES_FAILURE_LIMIT, configurable). - Lockout is scoped by (IP + username) and (username + user-agent).
- Reset-on-success is enabled.
- The proxy-aware client-IP resolver (
AXES_IPWARE_PROXY_COUNT) honorsX-Forwarded-Forwhen SWIRL is behind a trusted reverse proxy. - A superuser can clear a lockout from the Django admin — see Unlocking a Locked Account.
Session, Cookie, and CSRF Settings
When deployed in production (IN_PRODUCTION=True) SWIRL sets Django's SECURE_PROXY_SSL_HEADER to ('HTTP_X_FORWARDED_PROTO', 'https'), which causes Django to recognize HTTPS when TLS is terminated at an upstream proxy. This is the required pattern — SWIRL does not terminate TLS itself.
CSRF_TRUSTED_ORIGINSis configured via environment variable; set it to every origin that will load the Galaxy UI or call the API.CSP_FRAME_ANCESTORSdefaults to'self'; embedding SWIRL in other origins requires explicit allow-listing.CORS_ALLOWED_ORIGINSis empty by default. No cross-origin requests are permitted until explicitly configured.
Django SECRET_KEY
The Django SECRET_KEY is used for session signing, CSRF tokens, and password reset tokens. Generate a fresh, high-entropy value for every production deployment and store it in a secret manager. See The Django Secret Key for the supported generation command. Rotating the key invalidates all active sessions.
Authorization and Entitlements
SWIRL uses Django's User and Group model plus per-object ACLs:
- Groups are the unit of authorization. A
SearchProvidercan be restricted to one or more groups, so only members can execute or view searches against that source. - SuperUser accounts are equivalent to Django staff accounts and should be reserved for administrators.
- Object ownership — users only see their own
Search,Result, and (optionally)SearchProviderobjects, unless explicitly shared. See Object Ownership and Shared SearchProviders and Query Transformations. - User and Group management is available via the
/swirl/users/and/swirl/groups/APIs or the Django admin console. See SWIRL User & Group Support.
Source-side entitlement is preserved. A user whose OIDC identity does not map to a mailbox in Microsoft 365 will not retrieve content from that mailbox via SWIRL — SWIRL passes the user's token/credentials to the source and respects whatever ACL the source applies.
Credential Handling
Application and Infrastructure Secrets
All infrastructure secrets are read from environment variables (via django-environ). No secrets are ever committed to the repository or baked into container images. The environment variables SWIRL reads include:
| Variable | Purpose |
|---|---|
SECRET_KEY |
Django session / CSRF / token signing |
SQL_USER, SQL_PASSWORD, SQL_HOST, SQL_PORT, SQL_SSLMODE |
PostgreSQL connection and TLS mode |
CELERY_BROKER_URL, CELERY_RESULT_BACKEND, CACHE_REDIS_URL |
Redis endpoints (use rediss:// for TLS) |
OIDC_RP_CLIENT_ID, OIDC_RP_CLIENT_SECRET and related endpoints |
OIDC relying-party configuration |
SWIRL_LICENSE |
SWIRL Enterprise license key |
CSRF_TRUSTED_ORIGINS, ALLOWED_HOSTS, PROTOCOL |
Origin and host hardening |
In Kubernetes, store these in a Secret and never in a ConfigMap. See Store Secrets for the recommended pattern. On Docker Compose, inject via .env files that are excluded from version control or via an external secrets driver.
Source-System Credentials
Credentials used to query a source system are held on the SearchProvider record:
- For user-context sources (M365, Google, Box), SWIRL performs per-user OAuth2 and stores per-user tokens keyed to the Django user. Administrators never handle user access tokens directly.
- For service-account-style sources (bearer tokens,
X-Api-Key, Basic auth, query parameter keys), credentials are held in theSearchProvider.credentialsfield. See Supported Authentication Formats. - Use least-privilege service accounts per source and rotate them on a cadence appropriate to the data sensitivity.
AI Provider Credentials
LLM provider credentials (OpenAI, Azure OpenAI, Anthropic, Cohere, and any LiteLLM-supported endpoint) are held on the AIProvider record or, where applicable, injected as environment variables. A typical enterprise pattern is to point SWIRL at a private Azure OpenAI deployment or an on-network inference endpoint so that no prompt or content ever leaves the corporate network. See Connecting to Generative AI (GAI) and Large Language Models (LLMs).
Data Protection
Data Flow Summary
User --(HTTPS)--> Reverse Proxy --(HTTP/localnet)--> SWIRL
|
+-- PostgreSQL (metadata)
+-- Redis (queue / cache)
+-- Tika (text extraction)
+-- Source APIs (per query)
+-- AI Provider (per RAG/insight request)
- Source content flows through SWIRL transiently during a query. Full-text fetched by the PageFetcher is held only for the duration of the request/RAG pipeline.
- SWIRL's database stores metadata: users, groups,
SearchProviderdefinitions,Searchparameters, per-userResultobjects,Promptrecords,Authenticatorstate, andOauthTokenrows. It does not store a copy of the source corpus. - Redis holds Celery task state, session data, and ephemeral cache entries.
Transport Security
- External traffic must be HTTPS. Deploy SWIRL behind an HTTPS-terminating reverse proxy (Nginx, HAProxy, Azure Application Gateway, AWS ALB, or an Ingress controller). See Deploying SWIRL for Production Use.
- TLS is required for OIDC and OAuth2 callbacks (except
localhostduring development). The M365 and Google Workspace guides document the HTTPS requirement for those IdP flows. - PostgreSQL TLS is supported via
SQL_SSLMODE(require,verify-ca, orverify-fullare appropriate for production). PgBouncer (when enabled viaSWIRL_PGBOUNCER) passes SSL mode through to the upstream database. - Redis TLS — use
rediss://URLs forCELERY_BROKER_URL,CELERY_RESULT_BACKEND, andCACHE_REDIS_URLwhen connecting across untrusted networks, and require AUTH on the Redis instance.
Encryption at Rest
Encryption at rest is provided by the storage layer the customer chooses for PostgreSQL, Redis, and any persistent volumes:
- Managed PostgreSQL (Azure Database for PostgreSQL, Amazon RDS, Google Cloud SQL) — enable provider-native at-rest encryption and customer-managed keys where required.
- Self-managed PostgreSQL — use full-disk or LUKS encryption; use
pg_dump/pg_basebackupto encrypted targets for backup. - Kubernetes persistent volumes — provision on encrypted storage classes (EBS/GP3 encrypted, Azure Managed Disks with CMK, GCE PD encryption).
PII Detection and Redaction
SWIRL Enterprise integrates Microsoft Presidio for PII detection and redaction. Results can be redacted before they are returned to the user or included in an LLM prompt. Entities include names, emails, phone numbers, credit-card numbers, and national IDs. See PII Detection and Removal.
PII redaction is opt-in per SearchProvider by adding RedactPIIResultProcessor or RemovePIIResultProcessor to result_processors — this lets you enforce redaction on high-sensitivity connectors while leaving low-sensitivity ones unchanged.
Network Architecture and Egress
Inbound
- The Galaxy UI and REST API are served on port 8000 (configurable) behind the reverse proxy.
- The reverse proxy should be the only component exposed to untrusted networks. SWIRL's internal ports should never be public.
- WebSockets have been removed from the backend; all UI/API traffic is standard HTTPS/REST.
Internal
Pod-to-pod (or container-to-container) traffic:
- SWIRL ↔ PostgreSQL (5432)
- SWIRL ↔ Redis (6379)
- SWIRL ↔ Tika (9998)
- SWIRL ↔ Topic Text Matcher (7029)
Restrict this traffic with Kubernetes NetworkPolicy resources, security groups, or equivalent so only the SWIRL pod can reach the backing services.
Egress
SWIRL makes outbound calls to whatever the customer configures:
- Every
SearchProviderendpoint (e.g., SharePoint Graph, Confluence, Salesforce, Azure AI Search, Elastic, your ticketing system). - Every
AIProviderendpoint (OpenAI, Azure OpenAI, Anthropic, an on-prem inference server, etc.). - The customer's OIDC IdP for authentication flows.
Allow-list only what is needed at the egress firewall. SWIRL does not require egress to any SWIRL-hosted service at runtime.
Corporate Forward Proxy
When SWIRL is deployed in an environment that requires all egress to traverse a corporate forward proxy, set the standard HTTP_PROXY, HTTPS_PROXY, and NO_PROXY environment variables on the SWIRL container. Python's requests, Celery workers, and most connector libraries honor these. For connectors that establish long-running SDK sessions, verify proxy support in that SDK before deployment — SWIRL support can advise on a per-connector basis.
Deployment Hardening
Container and Image
- SWIRL Enterprise is distributed as signed container images from SWIRL's private registry. Customers pull with a time-limited registry credential that should be rotated on a cadence defined by policy.
- Pin image tags to a specific release (never
latest) and re-sign/re-scan before promotion. - The Docker image is based on Python 3.13-slim and removes unnecessary packages (including CUPS components, to mitigate CVE-2025-60060) during build.
Kubernetes Hardening Recommendations
In addition to what the Kubernetes Deployment Guide documents:
- Run SWIRL pods with
securityContext.runAsNonRoot: trueand areadOnlyRootFilesystemwhere your workflow allows. - Apply
NetworkPolicyresources so only the Ingress controller can reach SWIRL, and only SWIRL can reach PostgreSQL/Redis/Tika. - Use Pod Security Standards (restricted) at the namespace level.
- Use
cert-managerwith an enterprise CA (not just public Let's Encrypt) where certificate lineage matters for compliance. - Set
imagePullPolicy: IfNotPresentwith pinned digests to prevent drift. - Keep the Kubernetes cluster at 1.27+ (the supported minimum) and patch control-plane components on a defined schedule.
Docker Compose Hardening
- Bind SWIRL's published port only to
127.0.0.1when an on-host reverse proxy (Nginx/HAProxy) is the only intended entry point. - Use separate Docker networks to segment SWIRL from other co-located workloads on the host.
- Mount secrets via
secrets:orenv_file:pointing at files outside the repository, not inlineenvironment:blocks.
Audit Logging and Monitoring
SWIRL emits logs for:
- Django request lifecycle and authentication events (including
django-axeslogin/lockout events). - Celery task execution for asynchronous retrieval, RAG, and subscription tasks.
- Application events for search dispatch, result normalization, and AI pipeline steps.
Log locations, tailing commands, and rotation guidance are documented in the Monitoring Guide. Forwarding to a SIEM is typically done by running a sidecar log shipper (Fluent Bit, Vector, Splunk UF) against the SWIRL container's stdout. Ensure your retention policy matches your regulatory obligations.
Structured access logging at the reverse proxy is the recommended place to capture HTTP request telemetry for compliance purposes — SWIRL's application logs complement rather than replace proxy logs.
License Enforcement
SWIRL Enterprise validates its license on startup using RSA-PSS signature verification against a bundled public key. The license is signed by SWIRL and cannot be modified without invalidating the signature. The license defines the licensed owner, maximum user count, expiration, and enabled Enterprise feature flags. Expired or invalid licenses block new user creation; see your license agreement for the specific operating impact.
Vulnerability Management and Patching
Supported Versions
SWIRL Enterprise follows a versioned release cadence documented in the Enterprise Release Notes. Security patches are issued on the currently supported major/minor lines. Contact SWIRL Support to confirm which versions are receiving security updates at any given time.
Dependency Hygiene
SWIRL tracks third-party Python dependencies via pinned requirements files. License review and override decisions are captured in license_overrides.yml in the source tree. Customers who perform SBOM-based scanning can export an SBOM from the container image (e.g., with syft) and reconcile it against their own vulnerability feeds.
Reporting a Vulnerability
Report suspected vulnerabilities to support@swirlaiconnect.com with SECURITY in the subject line. Include:
- Your contact information
- Affected SWIRL Enterprise version
- A reproduction (steps, configuration, screenshots)
- Expected vs. observed behavior
The SWIRL Security Team acknowledges receipt within 72 hours. Please do not disclose vulnerabilities publicly before SWIRL has had an opportunity to remediate.
Customer Penetration Testing
Customers may conduct penetration tests against their own SWIRL deployments at any time without prior approval from SWIRL, provided the tests are limited to infrastructure the customer controls. SWIRL Support will accept and triage findings through the standard support channel.
Backup, Recovery, and Business Continuity
SWIRL's durable state is the PostgreSQL metadata database plus any mounted volumes (prompts, branding assets, uploaded media). A standard backup strategy:
- Daily
pg_dumpor managed-service automated backups of the SWIRL PostgreSQL database, written to encrypted storage with a retention policy matching RPO/RTO requirements. - Volume snapshots for persistent mounts (e.g.,
protected_media, branding overlays). - Redis is ephemeral — its contents can be rebuilt on restart and do not require backup.
- Test restores periodically; an untested backup is not a backup.
Re-deploying a clean SWIRL container against a restored database and the same environment variables produces a functionally equivalent environment.
Privacy and Compliance
Privacy Posture
Because SWIRL brokers queries against source systems rather than ingesting their content, the authoritative record of a given piece of data continues to live in the source of record, under its existing access controls and retention policy. SWIRL's own database stores metadata and per-user result pointers.
AI / LLM Data Handling
When RAG or AI Search Assistant is used, the following is sent to the configured AIProvider:
- The user's query (or a rewritten form of it)
- The retrieved result snippets selected for the prompt
- The configured system / RAG prompt
The AIProvider endpoint is customer-chosen. Customers with strict data-residency or privacy requirements typically deploy SWIRL against an in-region Azure OpenAI resource, an on-prem inference endpoint, or a provider with a contractual no-training commitment. PII Redaction (above) can further reduce what reaches the provider.
Regulatory Alignment
Customers operating under GDPR, HIPAA, SOC 2, ISO 27001, or similar frameworks are responsible for configuring SWIRL to meet the specific control requirements of those frameworks (encryption, access control, logging, retention, etc.). The controls documented on this page are the building blocks. SWIRL's enterprise team can provide configuration guidance and, under NDA, additional artifacts to support audits.
Incident Response
In the event of a suspected security incident affecting SWIRL Enterprise:
- Contain. Block ingress at the reverse proxy / Ingress controller and rotate the affected
SearchProviderandAIProvidercredentials. - Preserve evidence. Snapshot the SWIRL PostgreSQL database, capture container logs, and preserve any proxy and SIEM telemetry for the incident window.
- Rotate secrets. Rotate
SECRET_KEY, database passwords, Redis credentials, OIDC client secret, and any source-system credentials held onSearchProviderrecords. - Force re-authentication. Because sessions are signed with
SECRET_KEY, rotating it invalidates all active sessions and forces users to re-authenticate via the IdP. - Notify SWIRL. Contact SWIRL Support at support@swirlaiconnect.com and open a ticket at swirl.today/support-ticket.
Security Hardening Checklist
Before going to production:
- Deploy behind an HTTPS-terminating reverse proxy; enforce TLS 1.2+ and HSTS at the proxy.
- Generate a unique high-entropy
SECRET_KEYand store it in a secret manager. - Configure
ALLOWED_HOSTS,CSRF_TRUSTED_ORIGINS, andPROTOCOL=https. - Enable PostgreSQL TLS (
SQL_SSLMODE=verify-fullwhere possible) and Redis AUTH /rediss://. - Integrate SSO via OIDC; enforce MFA at the IdP; disable local password login for end users where feasible.
- Confirm
django-axeslockout thresholds meet your policy. - Assign users to Groups; scope
SearchProvidervisibility to the correct Groups. - Configure per-connector PII redaction where source data warrants it.
- Choose an
AIProviderthat satisfies your data-residency and no-training requirements. - Pin container image digests; rotate registry credentials.
- Apply Kubernetes
NetworkPolicy, non-rootsecurityContext, and restricted Pod Security Standards. - Ship logs to your SIEM from both SWIRL and the reverse proxy.
- Schedule daily encrypted PostgreSQL backups and test restores.
- Document who receives vulnerability reports and incident notifications internally.
- Subscribe to SWIRL Enterprise release notes for security advisories.