Γberblick
Secrets management describes how Ottili ONE protects your company's confidential configuration and integration data β JWT keys, session secrets, API keys, webhook and payment secrets. The guiding principle: no secret is hard-coded in source*. Every secret is injected via environment variables and validated at startup with a Pydantic settings model. This article describes Ottili ONE's source-backed secrets posture, clearly distinguishes verified from qualified, and links each mechanism to the right deep-dive article.
The higher-level security architecture is in the [Security overview](/docs/security-overview); tenant isolation and permissions are covered in [Tenant isolation](/docs/tenant-isolation) and [Roles and permissions](/docs/roles-and-permissions).
Environment-based secrets configuration (verified)
Ottili ONE injects all configuration and integration secrets β JWT, session, API keys, webhooks and payments β via environment variables and validates them at startup with a Pydantic settings model. Every secret is a required, environment-backed field*; there is no source-code literal for a secret.
Concretely, the following secrets are environment-backed (all verified against libs/common/config_manager_v1.py):
- Ottili Auth:*
jwt_access_secret/jwt_secret(minimum length enforced). - Ottili LD3:*
session_secret. - Ottili Coder (integration):*
api_key_secret,internal_secret,encryption_key. - Stripe (payments):*
secret_key,webhook_secret. - Shopify:*
api_secret. - eBay:*
client_secret.
Each of these components loads its secret from configuration, never from a hard-coded value. This means a deployment without the relevant environment variable will not start β the secret is never replaced by a default.
JWT signing secret from the environment (verified)
Ottili ONE signs and verifies access and refresh tokens with an HS256 algorithm whose key is loaded from the environment (OTTILI_AUTH_JWT_ACCESS_SECRET / jwt_access_secret). The signing function in libs/common/auth_helper.py decodes and validates the token with the shared secret sourced from configuration β not a value stored in code.
This keeps token signing consistent across every authenticated request and prevents a signing secret from ever landing in the repository.
No exposure over public endpoints (verified)
Public health and status endpoints (e.g. GET /api/health) expose only the presence of a configuration*, never the secret value itself. The response returns only boolean flags such as configured, mode or webhookConfigured.
Additionally, the endpoint sets Cache-Control: no-store and X-Robots-Tag: noindex, so the response is neither cached nor indexed by search engines. Even a publicly reachable endpoint therefore leaks no secret.
Sensitive-field redaction (verified)
When file or response content is scanned, Ottili ONE's security layer deliberately masks fields that carry secrets. The curated _SENSITIVE_FIELDS list (services/platform_api/file_system_security_layer.py) includes, among others:
passwordtokenapi_keyclient_secretprivate_keycredentialsencryption_key
This prevents the accidental disclosure of secrets from scanned files or API responses β even if such a field appears in a document.
Secrets excluded from version control (qualified)
Secret material lives in local keys/*.env files or the deployment secret store and is excluded from version control. .gitignore excludes .env, .env.*, keys/.env, keys/*.env, *.secret and secrets/, while the actual secrets-management code (services/secrets/*.py) and .env.example templates stay tracked. Developers copy keys/.env.example to keys/.env locally.
Honest assessment:* this point is *qualified*, not an absolute guarantee. It depends on the deployment secret store also honouring the same exclusion rule. The source-code side is clean β real secret values are never committed β but the overall guarantee only extends as far as the deployment store.
Recommendations for administrators
- Use a deployment secret store:* keep secrets in your secret store (e.g. host environment variables or a managed secret service), not in a repository
.env. - Never commit a real `.env`:* only
.env.exampletemplates belong in version control. - Rotate:* rotate secrets regularly and on suspicion of compromise; invalid secrets cause a controlled startup failure, not a silent fallback.
- Least privilege:* grant each service only the secrets it needs.
Status and availability
Ottili ONE clearly distinguishes Live, Beta, Private Beta, In Development, Planned and Concept. For secrets management:
- Verified (Live):* environment-based secrets injection with Pydantic validation, JWT signing from the environment (HS256), no secret exposure over public health/status endpoints, sensitive-field redaction during content scanning.
- Qualified:* excluding secret material from version control depends on the deployment secret store.
What the status terms mean is described in [Understand feature status labels](/docs/understand-feature-status-labels).
Related articles
- [Security overview](/docs/security-overview) β the whole security architecture at a glance.
- [Account and data security](/docs/account-and-data-security) β authentication, sessions, isolation, audit.
- [Tenant isolation](/docs/tenant-isolation) β how your company stays separate from others.
- [Roles and permissions](/docs/roles-and-permissions) β who may manage secrets.
- [Approval Queue](/docs/approval-queue) β human approval for sensitive actions.
- [Coder security](/docs/coder-security) β identity, secrets, isolation and audit for Ottili Coder.
- [Shared permissions and entitlements](/docs/shared-permissions-and-entitlements) β the cross-cutting permission model.
- [Understand feature status labels](/docs/understand-feature-status-labels) β what the status terms mean.
Was this article helpful?
