> ## Documentation Index
> Fetch the complete documentation index at: https://infisical.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Environment variables (self-hosted)

> Read how to configure environment variables for self-hosted Infisical.

Infisical accepts all configuration via environment variables. For a minimal self-hosted instance, at least `ENCRYPTION_KEY`, `AUTH_SECRET`, `DB_CONNECTION_URI`, and `REDIS_URL` must be defined.
However, you can configure additional settings to activate more features as needed.

## General platform

Used to configure platform-specific security and operational settings.

**ENCRYPTION\_KEY** `string` *required* (default: none)

Must be a random 16-byte hex string. Can be generated with `openssl rand -hex
    16`.

> [!WARNING]
>
> For FIPS-enabled deployments, `ENCRYPTION_KEY` must be a 256-bit
> base64-encoded key instead. Generate it with `openssl rand -base64 32`.

**AUTH\_SECRET** `string` *required* (default: none)

Must be a random 32-byte base64 string. Can be generated with `openssl rand
    -base64 32`.

**COOKIE\_SECRET\_SIGN\_KEY** `string` (default: generated per instance)

Signs the session cookies used by the OAuth SSO, SAML, OIDC, and LDAP login flows. Left unset,
Infisical derives a deterministic key from the KMS root key persisted for the deployment. All
replicas for that deployment use the same key. Set it to a random
32-byte base64 string, generated with `openssl rand -base64 32`, to manage the key yourself.
Changing the value ends every login already in progress.

**SITE\_URL** `string` *required* (default: none)

Must be an absolute URL including the protocol (e.g.
[https://app.infisical.com](https://app.infisical.com)).

**PORT** `int` (default: 8080)

Specifies the internal port on which the application listens.

**HOST** `string` (default: localhost)

Specifies the network interface Infisical will bind to when accepting incoming connections.

By default, Infisical binds to `localhost`, which restricts access to connections from the same machine.

To make the application accessible externally (e.g., for self-hosted deployments), set this to `0.0.0.0`, which tells the server to listen on all network interfaces.

Example values:

* `localhost` (default, same as `127.0.0.1`)
* `0.0.0.0` (all interfaces, accessible externally)
* `192.168.1.100` (specific interface IP)

**TELEMETRY\_ENABLED** `string` (default: true)

Telemetry helps us improve Infisical, but if you want to disable it, you may set
this to `false`.

**DISABLE\_UPDATE\_CHECK** `bool` (default: false)

Self-hosted instances check GitHub for the latest Infisical release once a week
(and once at startup) and show a subtle indicator in the UI when a newer version
is available. Set this to `true` to disable the check; no request is made to
GitHub when disabled.

Air-gapped deployments should set this to `true` to suppress the outbound
request entirely. Instances configured with an offline license disable the
check automatically.

**ALLOW\_INTERNAL\_IP\_CONNECTIONS** `bool` (default: false)

Global escape hatch that permits App Connections, Dynamic Secrets, and PKI
Certificate Discovery jobs to connect to internal/private IP addresses on the
**direct egress** path.

For reaching private resources, prefer the [Gateway](https://infisical.com/docs/documentation/platform/gateways/overview.md),
which tunnels traffic through an agent inside your network and doesn't require
opening any internal IP range on the Infisical instance. Use this flag (or the
more targeted `DYNAMIC_SECRET_ALLOW_INTERNAL_IP` / `AUDIT_LOG_STREAM_ALLOW_INTERNAL_IP` /
`S3_COMPATIBLE_STORAGE_ALLOW_INTERNAL_IP` flags) only for the features that egress directly,
without a Gateway.

> [!WARNING]
>
> Relaxes the SSRF protection. In addition to allowing private IPs, enabling
> this also disables DNS-rebinding pin protection for the affected direct-egress
> path (validation and connection may resolve to different IPs). Only enable it
> if you trust the users who can configure these integrations, and scope it as
> narrowly as possible using the per-feature flags.

**DYNAMIC\_SECRET\_ALLOW\_INTERNAL\_IP** `bool` (default: false)

Narrower, per-feature variant of `ALLOW_INTERNAL_IP_CONNECTIONS` that permits
only Dynamic Secrets to connect to internal/private IP addresses. Prefer this
over the global flag when only Dynamic Secrets need internal access.

> [!WARNING]
>
> Relaxes the SSRF protection for the Dynamic Secrets path, including disabling
> DNS-rebinding pin protection for that path. Prefer the [Gateway](https://infisical.com/docs/documentation/platform/gateways/overview.md)
> for private resources.

**SAFE\_REQUEST\_FORCE\_DIRECT\_EGRESS** `bool` (default: false)

Forces outbound requests made through Infisical's SSRF-safe HTTP client (App
Connections, Webhooks, Audit Log Streams, and similar direct-egress features)
to bypass any ambient forward proxy (sets axios `proxy: false`). This guarantees
the request connects to the exact IP that passed SSRF validation, closing a gap
where an `HTTP_PROXY` / `HTTPS_PROXY` would re-resolve the target and defeat the
IP pin.

Defaults to `false` so an operator-configured forward proxy keeps working.

> [!NOTE]
>
> Enable this only if your instance **doesn't** rely on an outbound
> `HTTP_PROXY` / `HTTPS_PROXY` for egress. When a proxy is in use, the IP pin
> can't extend past the proxy (the proxy resolves the target itself), so
> leaving this off is the correct choice for proxied deployments.

**KUBERNETES\_AUTO\_FETCH\_SERVICE\_ACCOUNT\_TOKEN** `bool` (default: false)

Determines whether your Infisical instance can automatically read the service
account token of the pod it's running on. Used for features such as the IRSA
auth method.

**TRUSTED\_PROXY\_CIDRS** `string`

Comma-separated list of trusted reverse-proxy CIDRs or named ranges whose forwarded-IP headers (e.g. `X-Forwarded-For`) Infisical will honor.

Accepted values are IPv4/IPv6 CIDR notation or the named aliases `loopback`, `linklocal`, and `uniquelocal`.

```
TRUSTED_PROXY_CIDRS=10.0.0.0/8,172.16.0.0/12,192.168.0.0/16
```

When set, only requests arriving from a socket address within this list will have their forwarded-IP headers respected. Requests from any other source fall back to using the raw socket IP. This prevents IP allowlist bypass via spoofed proxy headers.

When unset, Infisical trusts all forwarded-IP headers (legacy behavior, preserved for backwards compatibility with existing self-hosted deployments).

> [!WARNING]
>
> If your deployment sits behind a reverse proxy (e.g. NGINX, AWS ALB, Cloudflare), you should set this to the CIDR range of your proxy to prevent clients from spoofing their source IP. Leaving this unset is only safe when Infisical isn't reachable directly from the internet.

## CORS

Cross-Origin Resource Sharing (CORS) is a security feature that allows web applications running on one domain to access resources from another domain.
The following environment variables can be used to configure the Infisical REST API to allow or restrict access to resources from different origins.

**CORS\_ALLOWED\_ORIGINS** `string`

Specify a list of origins that are allowed to access the Infisical API.

An example value would be `CORS_ALLOWED_ORIGINS=["https://example.com"]`.

Defaults to the same value as your `SITE_URL` environment variable.

**CORS\_ALLOWED\_HEADERS** `string`

Specify a list of request headers that are allowed in CORS requests to the Infisical API.

An example value would be `CORS_ALLOWED_HEADERS=["Authorization","Content-Type"]`.

Defaults to reflecting the headers specified in the request's `Access-Control-Request-Headers` header.

## Data layer

The platform uses PostgreSQL to persist all of its data and Redis for caching and background tasks.

### PostgreSQL

> [!NOTE]
>
> Please note that the database user you create must be granted all privileges
> on the Infisical database. This includes the ability to create new schemas,
> create, update, delete, modify tables and indexes, etc.

**DB\_CONNECTION\_URI** `string` *required*

PostgreSQL database connection string.

**DB\_ROOT\_CERT** `string`

Configure the SSL certificate for securing a PostgreSQL connection by first encoding it in base64.
Use the following command to encode your certificate: `echo "<certificate>" | base64`

Many cloud providers provide a CA certificate for their data regions that you can use to secure your connection with SSL.

> [accordion] AWS RDS
>
> If you're hosting your database on AWS RDS, you can use their publicly available CA certificate as the database root certificate.
>
> You can find all the available CA certificates for AWS RDS on the official [AWS RDS documentation](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.SSL.html).
>
> As an example, if your RDS cluster is hosted in `us-east-1` *(US East, N. Virginia)*, you can use the following root certificate: [https://truststore.pki.rds.amazonaws.com/us-east-1/us-east-1-bundle.pem](https://truststore.pki.rds.amazonaws.com/us-east-1/us-east-1-bundle.pem).
>
> All the available CA certificates can be found in the AWS RDS documentation linked above.
>
> Remember to base64 encode the certificate before setting it as the `DB_ROOT_CERT` environment variable. `cat /path/to/certificate.pem | base64`.
>
> ```bash theme={"dark"}
> DB_ROOT_CERT=LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1 # .... (base64-encoded certificate)
> DB_CONNECTION_URI=<rds-endpoint>?sslmode=verify-ca # or verify-full depending on your security policies
> ```

**DB\_READ\_REPLICAS** `string`

PostgreSQL database read replica connection strings. It accepts a JSON string.

```
DB_READ_REPLICAS=[{"DB_CONNECTION_URI":""}]
```

**Format**

**DB\_CONNECTION\_URI** `string` *required*

PostgreSQL read replica connection string.

**DB\_ROOT\_CERT** `string`

Configure the SSL certificate for securing a PostgreSQL replica connection by first encoding it in base64.
Use the following command to encode your certificate: `echo "<certificate>" | base64`

If not provided it will use master SSL certificate.

#### Connection pool sizing (optional)

Each Infisical instance keeps its own pool of PostgreSQL connections. The defaults suit a small deployment and
most self-hosters never need to change them, but they become relevant once you run many instances: pools are
**per instance**, so the total number of connections your database sees grows with your instance count.

Work out your total like this:

```
per instance = DB_POOL_MAX
             + (DB_REPLICA_POOL_MAX x number of read replicas)
             + AUDIT_LOGS_DB_POOL_MAX   (only if AUDIT_LOGS_DB_CONNECTION_URI is set)

total        = per instance x number of instances
```

Then compare that total against your database's `max_connections` (`SHOW max_connections;`). Two things are
easy to miss:

* **Rolling deploys briefly double the total.** Old and new instances both hold pools while the rollout
  completes, so size against roughly twice your steady-state number.
* **Autoscaling sets the ceiling, not your current instance count.** If you autoscale, do the math with the
  maximum replica count, not today's.

Aim to keep the peak comfortably under `max_connections`, leaving headroom for migrations, admin tools, and
your own `psql` sessions. If you're close to the limit, **lower `DB_POOL_MAX`** rather than raising
`max_connections`: each PostgreSQL connection costs memory on the server, and a large number of mostly-idle
connections wastes it. If instead you see queries queueing while your database is idle, the pool is too small
and raising it is the right move.

> [!TIP]
>
> Prefer scaling reads with `DB_READ_REPLICAS` over enlarging the primary pool. A connection pooler such as
> PgBouncer or RDS Proxy is only worth the extra hop and failure domain once instance count alone pushes you
> near `max_connections`, and note that a pooler in transaction mode **doesn't** reclaim connections held
> open inside a transaction.

**DB\_POOL\_MIN** `int` (default: 0)

Minimum connections kept open in the primary database pool. `0` lets idle connections close, which is
usually what you want. Raise it only to avoid connection-setup latency on bursty traffic, and be aware that
a non-zero value holds connections open on the server even while the instance is idle.

**DB\_POOL\_MAX** `int` (default: 10)

Maximum connections in the primary database pool. Must be at least `1` and greater than or equal to
`DB_POOL_MIN`.

**DB\_REPLICA\_POOL\_MIN** `int` (default: 0)

Minimum connections kept open per read replica pool. Applies to each replica in `DB_READ_REPLICAS`
individually.

**DB\_REPLICA\_POOL\_MAX** `int` (default: 10)

Maximum connections **per read replica**. With three replicas and the default of `10`, each instance can
open up to 30 replica connections in addition to its primary pool.

### Audit log PostgreSQL (optional)

**AUDIT\_LOGS\_DB\_CONNECTION\_URI** `string`

Separate PostgreSQL connection string for audit log storage. If not set, audit logs are stored in the main database.

**AUDIT\_LOGS\_DB\_ROOT\_CERT** `string`

Base64-encoded CA certificate for the audit log PostgreSQL database connection. Only needed if `AUDIT_LOGS_DB_CONNECTION_URI` is set.

**AUDIT\_LOGS\_DB\_POOL\_MIN** `int` (default: 0)

Minimum connections kept open in the audit log database pool. Only used when
`AUDIT_LOGS_DB_CONNECTION_URI` is set.

**AUDIT\_LOGS\_DB\_POOL\_MAX** `int` (default: 10)

Maximum connections in the audit log database pool. Only used when `AUDIT_LOGS_DB_CONNECTION_URI` is set.
This pool is separate from the primary pool, so it adds to your per-instance total.

### ClickHouse (optional)

ClickHouse can be used as an alternative audit log storage backend for high-volume deployments. See the [ClickHouse Setup Guide](https://infisical.com/docs/documentation/platform/audit-logs-clickhouse-setup.md) for more details.

**CLICKHOUSE\_URL** `string`

ClickHouse connection URL. Example: `http://user:password@host:8123/database`

**CLICKHOUSE\_AUDIT\_LOG\_ENABLED** `string` (default: true)

Enable inserting audit logs into ClickHouse. Defaults to `true` when `CLICKHOUSE_URL` is set.

**CLICKHOUSE\_AUDIT\_LOG\_TABLE\_NAME** `string` (default: audit\_logs)

ClickHouse table name for audit logs.

**CLICKHOUSE\_AUDIT\_LOG\_ENGINE** `string` (default: ReplacingMergeTree)

ClickHouse engine for the audit logs table, used during table creation. Example: `ReplacingMergeTree` or `SharedReplacingMergeTree('/clickhouse/tables/{uuid}/{shard}', '{replica}')`.

**CLICKHOUSE\_AUDIT\_LOG\_INSERT\_SETTINGS** `string`

ClickHouse insert settings as a JSON string. Applied when inserting audit logs.

Default: `{"async_insert":1,"wait_for_async_insert":0,"date_time_input_format":"best_effort"}`

### Audit log behavior

**DISABLE\_POSTGRES\_AUDIT\_LOG\_STORAGE** `string` (default: false)

Disable storing audit logs in PostgreSQL. When set to `true`, audit logs aren't written to PostgreSQL but are still sent to ClickHouse (if configured) and any configured [audit log streams](https://infisical.com/docs/documentation/platform/audit-log-streams/audit-log-streams.md).

**AUDIT\_LOG\_STREAMS\_ENABLED** `string` (default: true)

Enable sending audit logs to external [audit log streams](https://infisical.com/docs/documentation/platform/audit-log-streams/audit-log-streams.md). When set to `false`, no events are sent to configured stream destinations, but PostgreSQL and ClickHouse storage are unaffected.

**DISABLE\_AUDIT\_LOG\_GENERATION** `string` (default: false)

Disable audit log generation entirely. When set to `true`, no audit log events are produced, so neither PostgreSQL, ClickHouse, nor audit log streams will receive events.

**AUDIT\_LOG\_STREAM\_ALLOW\_INTERNAL\_IP** `bool` (default: false)

Determines whether Audit Log Streams are permitted to connect with internal/private IP addresses.

> [!WARNING]
>
> Relaxes the SSRF protection. Only enable it if you trust the users who can configure streams.

**S3\_COMPATIBLE\_STORAGE\_ALLOW\_INTERNAL\_IP** `bool` (default: false)

Determines whether S3-Compatible Storage connections can reach an [allowed storage hostname](https://infisical.com/docs/documentation/platform/admin-panel/server-admin.md#allowed-storage-hostnames) that resolves to an internal/private IP address, such as a MinIO server on your network.

> [!WARNING]
>
> Relaxes the SSRF protection for these connections and turns off their DNS-rebinding pin protection. Only enable it if you trust the users who can configure app connections.

### Redis

Redis is used for caching and background tasks. You can use either a standalone Redis instance, Redis Sentinel, or Redis Cluster setup.

Redis is required: the instance won't start unless one of `REDIS_URL`, `REDIS_SENTINEL_HOSTS`, or
`REDIS_CLUSTER_HOSTS` is set.

> [!NOTE]
>
> An **active-passive** setup is recommended for Redis. Infisical hasn't been tested with an **active-active** Redis setup, which may result in undocumented behavior.

> [tab] Redis Standalone
>
> **REDIS\_URL** `string` *required* (default: none)
>
> Redis connection string. For SSL/TLS connections, use the `rediss://` protocol (note the double 's').
>
> Examples:
>
> * Without SSL: `redis://localhost:6379`
> * With SSL: `rediss://localhost:6379`
> * With authentication: `redis://:password@localhost:6379`
> * With SSL and authentication: `rediss://:password@localhost:6379`

> [tab] Redis Sentinel
>
> **REDIS\_SENTINEL\_HOSTS** `string` *required* (default: none)
>
> Comma-separated list of Sentinel host:port pairs. `      192.168.65.254:26379,192.168.65.254:26380`
>
> **REDIS\_SENTINEL\_MASTER\_NAME** `string` (default: mymaster)
>
> The name of the Redis master set monitored by Sentinel
>
> **REDIS\_SENTINEL\_ENABLE\_TLS** `bool` (default: false)
>
> Whether to use TLS/SSL for Redis Sentinel connection
>
> **REDIS\_SENTINEL\_USERNAME** `string` (default: none)
>
> Authentication username for Redis Sentinel
>
> **REDIS\_SENTINEL\_PASSWORD** `string` (default: none)
>
> Authentication password for Redis Sentinel
>
> **REDIS\_USERNAME** `string` (default: none)
>
> Authentication username for Redis Node
>
> **REDIS\_PASSWORD** `string` (default: none)
>
> Authentication password for Redis Node

> [tab] Redis Cluster
>
> **REDIS\_CLUSTER\_HOSTS** `string` *required* (default: none)
>
> Comma-separated list of Redis Cluster host:port pairs. `      192.168.65.254:26379,192.168.65.254:26380`
>
> **REDIS\_CLUSTER\_ENABLE\_TLS** `boolean` (default: false)
>
> Enable Redis TLS encryption on connection.
>
> **REDIS\_CLUSTER\_AWS\_ELASTICACHE\_DNS\_LOOKUP\_MODE** `boolean` (default: false)
>
> Enable this if you're using in-transit encryption for an AWS ElastiCache cluster. For more information, refer to the [ioredis documentation](https://github.com/redis/ioredis?tab=readme-ov-file#special-note-aws-elasticache-clusters-with-tls).
>
> **REDIS\_USERNAME** `string` (default: none)
>
> Authentication username for Redis Node
>
> **REDIS\_PASSWORD** `string` (default: none)
>
> Authentication password for Redis Node

> [tab] Redis Read Replica
>
> **REDIS\_READ\_REPLICAS** `string` (default: none)
>
> Comma-separated list of Redis read replicas host:port pairs. `      192.168.65.254:26379,192.168.65.254:26380`
>
> Parameters such as username, password, TLS, and Redis type are inherited from the primary instance.

### Redis with SSL/TLS

To connect to Redis with SSL/TLS, use the `rediss://` protocol (note the double 's') in your connection string.

If your Redis server uses a certificate signed by a private CA or a self-signed certificate, set the `NODE_EXTRA_CA_CERTS` environment variable to the path of your CA certificate file:

```bash theme={"dark"}
REDIS_URL=rediss://your-redis-host:6379
NODE_EXTRA_CA_CERTS=/path/to/ca.crt
```

For Redis Sentinel or Cluster mode, use the `REDIS_SENTINEL_ENABLE_TLS` or `REDIS_CLUSTER_ENABLE_TLS` environment variables respectively.

### Object storage (optional)

Set these variables to give the instance an Amazon S3 bucket for Agent Vault session logs, called default storage. Without it, organizations can only store session logs in their own bucket. To create the bucket and its IAM policy, see [Default storage for session logs](https://infisical.com/docs/self-hosting/guides/session-log-storage.md).

If you set only some of these variables, such as a bucket without a region, Infisical doesn't start.

**OBJECT\_STORAGE\_S3\_BUCKET** `string`

The name of a general purpose S3 bucket. Requires `OBJECT_STORAGE_S3_REGION`.

**OBJECT\_STORAGE\_S3\_REGION** `string`

The AWS region of the bucket, such as `us-east-1`. Requires `OBJECT_STORAGE_S3_BUCKET`.

**OBJECT\_STORAGE\_S3\_PREFIX** `string`

The folder in the bucket to store files under, such as `infisical`. Up to 256 characters: letters, numbers, and `! - _ . ' ( ) /`, with no slash at the start or end.

**OBJECT\_STORAGE\_S3\_ACCESS\_KEY\_ID** `string`

The access key ID of an IAM user that can use the bucket. Set it together with `OBJECT_STORAGE_S3_SECRET_ACCESS_KEY`. If you leave out both, Infisical finds credentials the way the AWS SDK does by default, for example from the instance's role.

**OBJECT\_STORAGE\_S3\_SECRET\_ACCESS\_KEY** `string`

The secret access key for `OBJECT_STORAGE_S3_ACCESS_KEY_ID`.

## Email service

Without email configuration, Infisical's core functions like sign-up/login and secret operations work, but this disables multi-factor authentication, email invites for projects, alerts for suspicious logins, and all other email-dependent features.

> [accordion] Generic Configuration
>
> **SMTP\_HOST** `string` (default: none)
>
> Hostname to connect to for establishing SMTP connections
>
> **SMTP\_PORT** `string` (default: 587)
>
> Port to connect to for establishing SMTP connections
>
> **SMTP\_USERNAME** `string` (default: none)
>
> Credential to connect to host (e.g. [you@example.com](mailto:you@example.com))
>
> **SMTP\_PASSWORD** `string` (default: none)
>
> Credential to connect to host
>
> **SMTP\_FROM\_ADDRESS** `string` (default: none)
>
> Email address to be used for sending emails
>
> **SMTP\_FROM\_NAME** `string` (default: none)
>
> Name label to be used in From field (e.g. Team)
>
> **SMTP\_HELO\_HOST** `string` (default: none)
>
> Hostname that Infisical announces in the SMTP `EHLO`/`HELO` greeting. When
> unset, the underlying mailer falls back to the operating system hostname.
> Inside containers (e.g. Cloud Run, Kubernetes) the OS hostname is typically a
> random container ID, which can be rejected by SMTP relays that validate the
> sender hostname (such as Gmail SMTP relay with sender-hostname checks). Set
> this to a valid FQDN that the relay accepts.
>
> **SMTP\_IGNORE\_TLS** `bool` (default: false)
>
> If this is `true` and `SMTP_PORT` isn't 465 then TLS isn't used even if the
> server supports STARTTLS extension.
>
> **SMTP\_REQUIRE\_TLS** `bool` (default: true)
>
> If this is `true` and `SMTP_PORT` isn't 465 then Infisical tries to use
> STARTTLS even if the server doesn't advertise support for it. If the
> connection can't be encrypted, then the message isn't sent.
>
> **SMTP\_TLS\_REJECT\_UNAUTHORIZED** `bool` (default: true)
>
> If this is `true`, Infisical will validate the server's SSL/TLS certificate
> and reject the connection if the certificate is invalid or not trusted. If set
> to `false`, the client will accept the server's certificate regardless of its
> validity, which can be useful in development or testing environments but is
> not recommended for production use.
>
> **SMTP\_CUSTOM\_CA\_CERT** `string` (default: none)
>
> If your SMTP server uses a certificate signed by a custom Certificate Authority, you should set this variable so that Infisical can trust the custom CA.
>
> This variable **must be a base64-encoded PEM certificate**. Use the following command to encode your certificate: `echo "<certificate>" | base64`
>
> Infisical strongly recommends using the following variables alongside this one for maximum security:
>
> * `SMTP_REQUIRE_TLS=true`
> * `SMTP_TLS_REJECT_UNAUTHORIZED=true`

> [accordion] Twilio SendGrid
>
> 1. Create an account and configure [SendGrid](https://sendgrid.com) to send emails.
> 2. Create a SendGrid API Key under Settings > [API Keys](https://app.sendgrid.com/settings/api_keys)
> 3. Set a name for your API Key, we recommend using "Infisical," and select the "Restricted Key" option. You'll need to enable the "Mail Send" permission as shown below:
>
> ![creating sendgrid api key](https://mintlify.s3.us-west-1.amazonaws.com/infisical/images/self-hosting/configuration/email/email-sendgrid-create-key.png)
>
> ![setting sendgrid api key restriction](https://mintlify.s3.us-west-1.amazonaws.com/infisical/images/self-hosting/configuration/email/email-sendgrid-restrictions.png)
>
> 4. With the API Key, you can now set your SMTP environment variables:
>
> ```
> SMTP_HOST=smtp.sendgrid.net
> SMTP_USERNAME=apikey
> SMTP_PASSWORD=SG.rqFsfjxYPiqE1lqZTgD_lz7x8IVLx # your SendGrid API Key from step above
> SMTP_PORT=587
> SMTP_FROM_ADDRESS=hey@example.com # your email address being used to send out emails
> SMTP_FROM_NAME=Infisical
> ```
>
> > [!NOTE]
> >
> > Remember that you'll need to restart Infisical for this to work properly.

> [accordion] Mailgun
>
> 1. Create an account and configure [Mailgun](https://www.mailgun.com) to send emails.
> 2. Obtain your Mailgun credentials in Sending > Overview > SMTP
>
> ![obtain Mailhog credentials](https://mintlify.s3.us-west-1.amazonaws.com/infisical/images/self-hosting/configuration/email/email-mailhog-credentials.png)
>
> 3. With your Mailgun credentials, you can now set up your SMTP environment variables:
>
> ```
> SMTP_HOST=smtp.mailgun.org # obtained from credentials page
> SMTP_USERNAME=postmaster@example.mailgun.org # obtained from credentials page
> SMTP_PASSWORD=password # obtained from credentials page
> SMTP_PORT=587
> SMTP_FROM_ADDRESS=hey@example.com # your email address being used to send out emails
> SMTP_FROM_NAME=Infisical
> ```

> [accordion] AWS SES
>
> **1. Create a verified identity**
>
> This will be used to verify the email you're sending from.
>
> ![Create SES identity](https://mintlify.s3.us-west-1.amazonaws.com/infisical/images/self-hosting/configuration/email/ses-create-identity.png)
>
> > [!NOTE]
> >
> > If AWS SES is in sandbox mode, you'll only be able to send emails to verified identities.
>
> **2. Create an account and configure AWS SES**
>
> Create an IAM user for SMTP authentication and obtain SMTP credentials in SMTP settings > Create SMTP credentials
>
> ![opening AWS SES console](https://mintlify.s3.us-west-1.amazonaws.com/infisical/images/self-hosting/configuration/email/email-aws-ses-console.png)
>
> ![creating AWS IAM SES user](https://mintlify.s3.us-west-1.amazonaws.com/infisical/images/self-hosting/configuration/email/email-aws-ses-user.png)
>
> **3. Set up your SMTP environment variables**
>
> With your AWS SES SMTP credentials, you can now set up your SMTP environment variables for your Infisical instance.
>
> ```
> SMTP_HOST=email-smtp.ap-northeast-1.amazonaws.com # SMTP endpoint obtained from SMTP settings
> SMTP_USERNAME=xxx # your SMTP username
> SMTP_PASSWORD=xxx # your SMTP password
> SMTP_PORT=465
> SMTP_FROM_ADDRESS=hey@example.com # your email address being used to send out emails
> SMTP_FROM_NAME=Infisical
> ```
>
> > [!NOTE]
> >
> > Remember that you will need to restart Infisical for this to work properly.

> [accordion] SocketLabs
>
> 1. Create an account and configure [SocketLabs](https://www.socketlabs.com/) to send emails.
> 2. From the dashboard, navigate to SMTP Credentials > SMTP & APIs > SMTP Credentials to obtain your SocketLabs SMTP credentials.
>
> ![opening SocketLabs dashboard](https://mintlify.s3.us-west-1.amazonaws.com/infisical/images/self-hosting/configuration/email/email-socketlabs-dashboard.png)
>
> ![obtaining SocketLabs credentials](https://mintlify.s3.us-west-1.amazonaws.com/infisical/images/self-hosting/configuration/email/email-socketlabs-credentials.png)
>
> 3. With your SocketLabs SMTP credentials, you can now set up your SMTP environment variables:
>
> ```
> SMTP_HOST=smtp.socketlabs.com
> SMTP_USERNAME=username # obtained from your credentials
> SMTP_PASSWORD=password # obtained from your credentials
> SMTP_PORT=587
> SMTP_FROM_ADDRESS=hey@example.com # your email address being used to send out emails
> SMTP_FROM_NAME=Infisical
> ```
>
> &#x20;
>
> > [!NOTE]
> >
> > The `SMTP_FROM_ADDRESS` environment variable should be an email for an
> > authenticated domain under Configuration > Domain Management in SocketLabs.
> > For example, if you're using SocketLabs in sandbox mode, then you may use an
> > email like `team@sandbox.socketlabs.dev`.
>
> ![SocketLabs domain management](https://mintlify.s3.us-west-1.amazonaws.com/infisical/images/self-hosting/configuration/email/email-socketlabs-domains.png)
>
> > [!NOTE]
> >
> > Remember that you will need to restart Infisical for this to work properly.

> [accordion] Resend
>
> 1. Create an account on [Resend](https://resend.com).
> 2. Add a [Domain](https://resend.com/domains).
>
> ![adding resend domain](https://mintlify.s3.us-west-1.amazonaws.com/infisical/images/self-hosting/configuration/email/email-resend-create-domain.png)
>
> 3. Create an [API Key](https://resend.com/api-keys).
>
> ![creating resend api key](https://mintlify.s3.us-west-1.amazonaws.com/infisical/images/self-hosting/configuration/email/email-resend-create-key.png)
>
> 4. Go to the [SMTP page](https://resend.com/settings/smtp) and copy the values.
>
> ![go to resend smtp settings](https://mintlify.s3.us-west-1.amazonaws.com/infisical/images/self-hosting/configuration/email/email-resend-smtp-settings.png)
>
> 5. With the API Key, you can now set your SMTP environment variables:
>
> ```
> SMTP_HOST=smtp.resend.com
> SMTP_USERNAME=resend
> SMTP_PASSWORD=YOUR_API_KEY
> SMTP_PORT=587
> SMTP_FROM_ADDRESS=hey@example.com # your email address being used to send out emails
> SMTP_FROM_NAME=Infisical
> ```
>
> > [!NOTE]
> >
> > Remember that you will need to restart Infisical for this to work properly.

> [accordion] Gmail
>
> Create an account and enable "less secure app access" in Gmail Account Settings > Security. This will allow
> applications like Infisical to authenticate with Gmail via your username and password.
>
> ![Gmail secure app access](https://mintlify.s3.us-west-1.amazonaws.com/infisical/images/self-hosting/configuration/email/email-gmail-app-access.png)
>
> With your Gmail username and password, you can set your SMTP environment variables:
>
> ```
> SMTP_HOST=smtp.gmail.com
> SMTP_USERNAME=hey@gmail.com # your email
> SMTP_PASSWORD=password # your password
> SMTP_PORT=587
> SMTP_FROM_ADDRESS=hey@gmail.com
> SMTP_FROM_NAME=Infisical
> ```
>
> > [!WARNING]
> >
> > As per the [notice](https://support.google.com/accounts/answer/6010255?hl=en) by Google, you should note that using Gmail credentials for SMTP configuration
> > will only work for Google Workspace or Google Cloud Identity customers as of May 30, 2022.
> >
> > Put differently, the SMTP configuration is only possible with business (not personal) Gmail credentials.

> [accordion] Office365
>
> 1. Create an account and configure [Office365](https://www.office.com/) to send emails.
>
> 2. With your login credentials, you can now set up your SMTP environment variables:
>
> ```
> SMTP_HOST=smtp.office365.com
> SMTP_USERNAME=username@yourdomain.com # your username
> SMTP_PASSWORD=password # your password
> SMTP_PORT=587
> SMTP_FROM_ADDRESS=username@yourdomain.com
> SMTP_FROM_NAME=Infisical
> ```

> [accordion] Zoho Mail
>
> 1. Create an account and configure [Zoho Mail](https://www.zoho.com/mail/) to send emails.
>
> 2. With your email credentials, you can now set up your SMTP environment variables:
>
> ```
> SMTP_HOST=smtp.zoho.com
> SMTP_USERNAME=username # your email
> SMTP_PASSWORD=password # your password
> SMTP_PORT=587
> SMTP_FROM_ADDRESS=hey@example.com # your personal Zoho email or domain-based email linked to Zoho Mail
> SMTP_FROM_NAME=Infisical
> ```
>
> &#x20;
>
> > [!NOTE]
> >
> > You can use either your personal Zoho email address like `you@zohomail.com` or
> > a domain-based email address like `you@yourdomain.com`. If using a
> > domain-based email address, then please make sure that you've configured and
> > verified it with Zoho Mail.
>
> > [!NOTE]
> >
> > Remember that you will need to restart Infisical for this to work properly.

> [accordion] SMTP2Go
>
> 1. Create an account and configure [SMTP2Go](https://www.smtp2go.com/) to send emails.
> 2. Turn on SMTP authentication
>
> ```
> SMTP_HOST=mail.smtp2go.com
> SMTP_PORT=You can use one of the following ports: 2525, 80, 25, 8025, or 587
> SMTP_USERNAME=username #Your SMTP2GO account's SMTP username
> SMTP_PASSWORD=password #Your SMTP2GO account's SMTP password
> SMTP_FROM_ADDRESS=hey@example.com # your email address being used to send out emails
> SMTP_FROM_NAME=Infisical
> ```
>
> &#x20;
>
> > [!NOTE]
> >
> > Optional (for TLS/SSL):
> >
> > TLS: Available on the same ports (2525, 80, 25, 8025, or 587)
> > SSL: Available on ports 465, 8465, and 443

## Authentication

By default, users can only log in via the email/password-based login method.
To log in to Infisical with OAuth providers such as Google, configure the associated variables.

**DEFAULT\_SAML\_ORG\_SLUG** `string`

When set, all visits to the Infisical login page will automatically redirect users of your Infisical instance to the SAML identity provider associated with the specified organization slug.

> [accordion] Google
>
> Follow the detailed guide to configure [Google SSO](https://infisical.com/docs/documentation/platform/sso/google.md).
>
> **CLIENT\_ID\_GOOGLE\_LOGIN** `string` (default: none)
>
> OAuth2 client ID for Google login
>
> **CLIENT\_SECRET\_GOOGLE\_LOGIN** `string` (default: none)
>
> OAuth2 client secret for Google login

> [accordion] GitHub
>
> Follow the detailed guide to configure [GitHub SSO](https://infisical.com/docs/documentation/platform/sso/github.md).
>
> **CLIENT\_ID\_GITHUB\_LOGIN** `string` (default: none)
>
> OAuth2 client ID for GitHub login
>
> **CLIENT\_SECRET\_GITHUB\_LOGIN** `string` (default: none)
>
> OAuth2 client secret for GitHub login

> [accordion] GitLab
>
> Follow the detailed guide to configure [GitLab SSO](https://infisical.com/docs/documentation/platform/sso/gitlab.md).
>
> **CLIENT\_ID\_GITLAB\_LOGIN** `string` (default: none)
>
> OAuth2 client ID for GitLab login
>
> **CLIENT\_SECRET\_GITLAB\_LOGIN** `string` (default: none)
>
> OAuth2 client secret for GitLab login
>
> **URL\_GITLAB\_LOGIN** `string` (default: [https://gitlab.com](https://gitlab.com))
>
> URL of your self-hosted instance of GitLab where the OAuth application is registered

> [accordion] Okta SAML
>
> Requires enterprise license. Please contact [sales@infisical.com](mailto:sales@infisical.com) to get more
> information.

> [accordion] Azure SAML
>
> Requires enterprise license. Please contact [sales@infisical.com](mailto:sales@infisical.com) to get more
> information.

> [accordion] JumpCloud SAML
>
> Requires enterprise license. Please contact [sales@infisical.com](mailto:sales@infisical.com) to get more
> information.

## App connections

You can configure third-party app connections for re-use across Infisical Projects.

> [accordion] AWS Assume Role Connection
>
> **INF\_APP\_CONNECTION\_AWS\_ACCESS\_KEY\_ID** `string` (default: none)
>
> The AWS IAM User access key ID for assuming roles
>
> **INF\_APP\_CONNECTION\_AWS\_SECRET\_ACCESS\_KEY** `string` (default: none)
>
> The AWS IAM User secret key for assuming roles

> [accordion] GitHub App Connection
>
> **INF\_APP\_CONNECTION\_GITHUB\_APP\_ID** `string` (default: none)
>
> The ID of the GitHub App
>
> **INF\_APP\_CONNECTION\_GITHUB\_APP\_SLUG** `string` (default: none)
>
> The slug of the GitHub App
>
> **INF\_APP\_CONNECTION\_GITHUB\_APP\_CLIENT\_ID** `string` (default: none)
>
> The client ID for the GitHub App
>
> **INF\_APP\_CONNECTION\_GITHUB\_APP\_CLIENT\_SECRET** `string` (default: none)
>
> The client secret for the GitHub App
>
> **INF\_APP\_CONNECTION\_GITHUB\_APP\_PRIVATE\_KEY** `string` (default: none)
>
> The private key for the GitHub App
>
> **INF\_APP\_CONNECTION\_GITHUB\_APP\_HOST** `string` (default: github.com)
>
> The hostname of the GitHub instance where the shared GitHub App is registered. Only required when the shared GitHub App is registered on a GitHub Enterprise Server (GHES) instance rather than github.com (e.g. `github.mycompany.com`). Defaults to `github.com` when not set.

> [accordion] GitHub Radar App Connection
>
> **INF\_APP\_CONNECTION\_GITHUB\_RADAR\_APP\_ID** `string` (default: none)
>
> The ID of the GitHub Radar App
>
> **INF\_APP\_CONNECTION\_GITHUB\_RADAR\_APP\_SLUG** `string` (default: none)
>
> The slug of the GitHub Radar App
>
> **INF\_APP\_CONNECTION\_GITHUB\_RADAR\_APP\_CLIENT\_ID** `string` (default: none)
>
> The client ID for the GitHub Radar App
>
> **INF\_APP\_CONNECTION\_GITHUB\_RADAR\_APP\_CLIENT\_SECRET** `string` (default: none)
>
> The client secret for the GitHub Radar App
>
> **INF\_APP\_CONNECTION\_GITHUB\_RADAR\_APP\_PRIVATE\_KEY** `string` (default: none)
>
> The private key for the GitHub Radar App
>
> **INF\_APP\_CONNECTION\_GITHUB\_RADAR\_APP\_WEBHOOK\_SECRET** `string` (default: none)
>
> The webhook secret configured for payload verification in the GitHub Radar App

> [accordion] GitHub OAuth Connection
>
> **INF\_APP\_CONNECTION\_GITHUB\_OAUTH\_CLIENT\_ID** `string` (default: none)
>
> The OAuth2 client ID for GitHub OAuth Connection
>
> **INF\_APP\_CONNECTION\_GITHUB\_OAUTH\_CLIENT\_SECRET** `string` (default: none)
>
> The OAuth2 client secret for GitHub OAuth Connection

> [accordion] GitLab OAuth Connection
>
> **INF\_APP\_CONNECTION\_GITLAB\_OAUTH\_CLIENT\_ID** `string` (default: none)
>
> The Application ID of your GitLab OAuth application.
>
> **INF\_APP\_CONNECTION\_GITLAB\_OAUTH\_CLIENT\_SECRET** `string` (default: none)
>
> The Secret of your GitLab OAuth application.

> [accordion] Heroku OAuth Connection
>
> **INF\_APP\_CONNECTION\_HEROKU\_OAUTH\_CLIENT\_ID** `string` (default: none)
>
> The Application ID of your Heroku OAuth application.
>
> **INF\_APP\_CONNECTION\_HEROKU\_OAUTH\_CLIENT\_SECRET** `string` (default: none)
>
> The Secret of your Heroku OAuth application.

## Secret scanning

> [accordion] GitHub
>
> **SECRET\_SCANNING\_GIT\_APP\_ID** `string` (default: none)
>
> The App ID of your GitHub App.
>
> &#x20;
>
> **SECRET\_SCANNING\_GIT\_APP\_SLUG** `string` (default: none)
>
> The slug of your GitHub App.
>
> &#x20;
>
> **SECRET\_SCANNING\_PRIVATE\_KEY** `string` (default: none)
>
> A private key for your GitHub App.
>
> **SECRET\_SCANNING\_WEBHOOK\_SECRET** `string` (default: none)
>
> The webhook secret of your GitHub App.

> [accordion] Scan limits
>
> These bound the resources a single scan can consume. The defaults only trip on outliers, such as
> a repository large enough to exhaust a worker, so most deployments never need to change them.
>
> > [!NOTE]
> >
> > The limits apply from the release that introduces them, on existing instances too. A repository
> > above `SECRET_SCANNING_MAX_REPO_SIZE_MB` that scanned before the upgrade is now rejected: before
> > cloning when the provider reports a size, otherwise once the clone is measured on disk. The
> > scanner also runs under a memory ceiling it previously did not have. If you scan repositories
> > larger than the defaults, raise both values or set them to `0` for the previous unbounded
> > behaviour.
>
> &#x20;
>
> **SECRET\_SCANNING\_SCAN\_TIMEOUT** `string` (default: 10m)
>
> How long a single scan may run before it is cancelled and the scan is marked
> failed. Takes a duration string such as `90s`, `10m`, or `2h`. Defaults to
> `10m`.
>
> &#x20;
>
> **SECRET\_SCANNING\_CLONE\_TIMEOUT** `string` (default: 10m)
>
> How long cloning a repository may take before it is cancelled and the scan is
> marked failed. Takes a duration string such as `90s`, `10m`, or `2h`. Defaults
> to `10m`.
>
> &#x20;
>
> **SECRET\_SCANNING\_MEMORY\_LIMIT\_MB** `number` (default: 2048)
>
> Soft memory ceiling for the scanner process, in MB. It collects garbage more
> aggressively as it approaches this limit rather than growing. Defaults to
> `2048` (2 GB). Set to `0` to disable.
>
> &#x20;
>
> **SECRET\_SCANNING\_CPU\_THREADS** `number` (default: 1)
>
> Maximum CPU threads a scan may use, applied to both the scanner process and
> the repository clone. Scans share the instance with the API, so raising this
> makes scans faster at the cost of API responsiveness during a scan. Defaults
> to `1`. Set to `0` to remove the cap.
>
> &#x20;
>
> **SECRET\_SCANNING\_MAX\_REPO\_SIZE\_MB** `number` (default: 5120)
>
> Repositories larger than this many MB are rejected instead of scanned.
> Defaults to `5120` (5 GB). Set to `0` to disable.

## Observability

You can configure Infisical to collect and expose telemetry data for analytics and monitoring.

**OTEL\_TELEMETRY\_COLLECTION\_ENABLED** `string` (default: false)

Whether to collect and expose telemetry data.

**OTEL\_EXPORT\_TYPE** `enum`

Supported types are `prometheus` and `otlp`.

If the export type is set to `prometheus`, metric data will be exposed on port 9464 at the `/metrics` path.

If the export type is set to `otlp`, you will have to configure a value for `OTEL_EXPORT_OTLP_ENDPOINT`.

**OTEL\_EXPORT\_OTLP\_ENDPOINT** `string`

Where telemetry data is pushed for collection. This is only
applicable when `OTEL_EXPORT_TYPE` is set to `otlp`.

**OTEL\_COLLECTOR\_BASIC\_AUTH\_USERNAME** `string`

The username for authenticating with the telemetry collector.

**OTEL\_COLLECTOR\_BASIC\_AUTH\_PASSWORD** `string`

The password for authenticating with the telemetry collector.

**OTEL\_DROP\_HIGH\_CARDINALITY\_METERS** `string` (default: false)

When set to `true`, Infisical stops recording the high-cardinality, per-actor `Infisical`, `API`, `SecretSyncs`, `PkiSyncs`, and `Integrations` meters. Nothing is measured, exported, or held in memory for them. Only bounded-cardinality `InfisicalCore` metrics are emitted. Recommended when those meters are enabled with `OTEL_EXPORT_TYPE=prometheus` and label combinations turn over often (many secret paths, source IPs, or clients), because memory then grows with uptime until the process restarts. See [Monitoring & Telemetry](https://infisical.com/docs/self-hosting/guides/monitoring-telemetry.md#available-metrics) for details.

**OTEL\_SEMCONV\_STABILITY\_OPT\_IN** `string` (default: http)

Which OpenTelemetry semantic conventions the HTTP metrics follow. Leave it unset and Infisical applies `http`, the stable conventions, and logs that it did so at startup.

Set it to `http/dup` to emit the old metric names alongside the stable ones while you move dashboards across. Both name sets are exported for as long as it's set, so the volume of those metrics roughly doubles. See [Monitoring & Telemetry](https://infisical.com/docs/self-hosting/guides/monitoring-telemetry.md#system-metrics) for the old and new names.

Tokens for other namespaces, such as `database`, are left alone.

## Identity auth method

**IDENTITY\_TLS\_CERT\_AUTH\_CLIENT\_CERTIFICATE\_HEADER\_KEY** `string` (default: x-identity-tls-cert-auth-client-cert)

The TLS header used to propagate the client certificate from the load balancer
to the server.

## Environment variable overrides

If you can't reach the environment variables of your deployment directly, override them from **Environment Variables** in the [Server Console](https://infisical.com/docs/documentation/platform/admin-panel/server-admin.md). A saved value takes up to five minutes to reach every container.

![Environment Variables Overrides Page](https://mintlify.s3.us-west-1.amazonaws.com/infisical/images/self-hosting/configuration/overrides/page.png)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.