mirror of
https://github.com/fosrl/docs-v2.git
synced 2026-09-19 04:19:09 +02:00
Add some pages about security
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
---
|
||||
title: "FIPS 140 and FedRAMP Considerations"
|
||||
description: "How Pangolin's WireGuard-based tunnels fit into FIPS 140 and FedRAMP-governed environments."
|
||||
---
|
||||
|
||||
<Note>
|
||||
This page explains where Pangolin's encryption stands relative to FIPS 140 and FedRAMP requirements. It is not compliance or legal advice - work with your ISSO or compliance team to determine what applies to your specific system boundary.
|
||||
</Note>
|
||||
|
||||
Every Pangolin tunnel - between a site connector and a node, or a client and a site - is a [WireGuard](/development/system-architecture#site-connectors) connection. WireGuard uses a fixed, modern cryptographic suite: Curve25519 for key exchange, ChaCha20-Poly1305 for encryption, and BLAKE2s for hashing. This cryptography is well-reviewed and considered strong, but "strong" and "FIPS 140-validated" are different things - validation refers specifically to a cryptographic module having gone through NIST's Cryptographic Module Validation Program (CMVP), and WireGuard's implementation has not gone through that process. As of this writing, Pangolin does not use a FIPS-validated module for its tunnel encryption.
|
||||
|
||||
## Where Pangolin can fit in a FedRAMP boundary
|
||||
|
||||
Not using a FIPS-validated module for the tunnel itself doesn't automatically disqualify Pangolin from a FedRAMP-authorized environment but it changes how you scope it:
|
||||
|
||||
- **Layer it, don't rely on it alone.** If your system already terminates FIPS-validated TLS or IPsec at its authorization boundary, a Pangolin tunnel can run as an additional encrypted layer inside or alongside that connection rather than being the control that has to satisfy FIPS validation on its own. FedRAMP guidance generally permits non-validated encryption in an inner layer when an outer layer already satisfies the relevant controls (commonly referenced as SC-8(1) and SC-28(1) for transmission and data-at-rest confidentiality).
|
||||
- **Decide where the boundary sits.** Work with your ISSO to determine, per NIST SP 800-18 and the impact categorization in FIPS 199, whether Pangolin operates inside your system's authorization boundary as a component, or outside it as a supporting service that carries traffic but isn't part of the accredited system itself.
|
||||
- **Treat it as a component, not the system of record.** Pangolin's [system architecture](/development/system-architecture) - control plane, nodes, connectors, and clients - is documented specifically so it can be mapped cleanly onto a system boundary diagram during this evaluation.
|
||||
|
||||
## Reducing what's outside your control
|
||||
|
||||
If keeping infrastructure inside an already-accredited boundary matters more than convenience, [self-hosting](/self-host/quick-install) is the relevant lever: the control plane and every node can run entirely on infrastructure you already operate and have assessed, rather than depending on Pangolin Cloud's shared infrastructure. [Enterprise Edition](/self-host/enterprise-edition) extends this with clustering, additional identity providers, and centralized logging for environments that need tighter operational control. If your organization needs a compliance package beyond what's documented here, [contact sales](mailto:sales@pangolin.net) to discuss your requirements directly.
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="System Architecture" icon="server" href="/development/system-architecture">
|
||||
Map Pangolin's components onto your system boundary.
|
||||
</Card>
|
||||
|
||||
<Card title="Self-Host Pangolin" icon="lock" href="/self-host/quick-install">
|
||||
Keep the control plane and nodes on infrastructure you already operate.
|
||||
</Card>
|
||||
|
||||
<Card title="Enterprise Edition" icon="building" href="/self-host/enterprise-edition">
|
||||
Clustering, additional identity providers, and centralized logging.
|
||||
</Card>
|
||||
|
||||
<Card title="Zero Trust Networking" icon="shield-halved" href="/about/security/zero-trust-networking">
|
||||
How Pangolin's encryption and authorization model is structured.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
@@ -0,0 +1,93 @@
|
||||
---
|
||||
title: "Least-Privilege Access"
|
||||
description: "Why scoping access down to what's actually needed matters, and how to enforce it with Pangolin's roles, policies, and approvals."
|
||||
---
|
||||
|
||||
Every organization eventually asks the same question: does this person, device, or integration really need to reach everything it currently can? Least-privilege access is the practice of answering "no" by default - granting each identity only the specific resources required for its job, and nothing kept around "just in case." It's sometimes called minimal access or need-to-know access, and it's one of the few security practices that pays off whether or not you're ever attacked, because it also limits how much damage a mistake can do.
|
||||
|
||||
## The balance admins actually have to strike
|
||||
|
||||
Scope access too loosely and a single compromised account, leaked token, or careless click can reach far more than it should. Scope it too tightly and people spend their day filing access requests instead of working, while whoever approves those requests turns into a bottleneck for routine tasks. Neither extreme is sustainable.
|
||||
|
||||
The practical goal isn't "as little access as physically possible" - it's a narrow default combined with a fast, auditable path to widen access temporarily when a real need comes up. A contractor who needs staging access for two weeks should get staging access for two weeks, not permanent access "since we'll probably need them again."
|
||||
|
||||
## What tight scoping actually buys you
|
||||
|
||||
- **Smaller blast radius.** If an account is compromised, the attacker inherits only what that account could reach - not the whole organization.
|
||||
- **Fewer moving parts per environment.** Fewer people with standing access to a given system means fewer unexpected changes and a more predictable environment.
|
||||
- **Faster incident response.** When access is scoped by role, you can immediately narrow "who could have done this" to the handful of people who actually had the ability to.
|
||||
- **Clearer ownership.** Access mapped to job function makes it obvious who's responsible for what, instead of everyone having a bit of everything.
|
||||
- **Easier onboarding and offboarding.** Assigning and removing a role is simpler than auditing an individual's sprawling permission history.
|
||||
- **Regulatory alignment.** Many compliance frameworks specifically expect access to be scoped to job function - this is one of the easier boxes to check when it's built in from the start rather than bolted on.
|
||||
|
||||
## How narrow scope limits real attacks
|
||||
|
||||
Most breaches don't start with an attacker breaking into everything at once - they start with one foothold, then depend on that foothold being able to reach more than it should. Tight scoping directly blunts this:
|
||||
|
||||
- **Escalation attempts stall out.** Whether an attacker is trying to climb from a low-privileged account into an administrative one, or hijack a peer's similarly-scoped credentials, there's simply less to climb into if roles are narrow to begin with.
|
||||
- **A single stolen credential goes less far.** Passwords get phished, reused, or leaked in unrelated breaches constantly. If that credential only unlocks one role's resources, the damage is contained.
|
||||
- **Malware can't pivot as easily.** Software that hijacks a session or a device inherits whatever that session could reach - nothing more.
|
||||
- **Insider risk shrinks.** A disgruntled or careless employee, whether acting deliberately or by mistake, can only affect the systems their role actually touches.
|
||||
|
||||
## Applying least privilege with Pangolin
|
||||
|
||||
Pangolin gives you the building blocks to enforce this without hand-managing individual permissions:
|
||||
|
||||
<Steps>
|
||||
<Step title="Scope by role, not by person">
|
||||
Group users into [roles](/manage/access-control/create-user#roles) - Operations, Contractor, Support, or any custom role you define - instead of granting access to individuals one at a time. Each [resource](/manage/resources/understanding-resources) specifies which roles can reach it, and a user's effective access is just the union of what their roles allow. Revoke a role and every resource it granted access to disappears with it.
|
||||
</Step>
|
||||
|
||||
<Step title="Keep policies consistent across resources">
|
||||
Rather than re-configuring authentication and access settings on every resource individually, define a [resource policy](/manage/resources/public/resource-policies) once and attach it wherever the same baseline should apply. This keeps a large number of resources from silently drifting out of sync with each other.
|
||||
</Step>
|
||||
|
||||
<Step title="Narrow further with rules">
|
||||
Layer in [access rules](/manage/access-control/rules) that allow, deny, or require authentication based on URL path, IP, CIDR range, country, or region - useful for exposing only the specific paths a role needs, or keeping traffic from regions you don't operate in out entirely. [Geo-blocking](/manage/geoblocking) and [ASN blocking](/manage/asnblocking) extend this to entire countries or networks, including known VPN, proxy, and datacenter ranges.
|
||||
</Step>
|
||||
|
||||
<Step title="Gate new or unrecognized devices">
|
||||
[Device approvals](/manage/access-control/approvals) require an administrator to review and approve any new device before it can connect, per role - useful for roles where you don't want valid credentials alone to be sufficient.
|
||||
</Step>
|
||||
|
||||
<Step title="Force re-verification instead of trusting it forever">
|
||||
[Session length](/manage/access-control/session-length) and [password rotation](/manage/access-control/password-rotation) policies make sure a credential earned once doesn't stay valid indefinitely. Pair this with [MFA](/manage/access-control/mfa) or hardware [security keys](/manage/access-control/security-keys) so a leaked password alone isn't enough to authenticate.
|
||||
</Step>
|
||||
|
||||
<Step title="Review what actually happened">
|
||||
[Admin action logs](/manage/analytics/action) give you an audit trail of configuration changes and administrative actions, so scoping decisions can be revisited based on evidence rather than guesswork.
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## A checklist worth revisiting periodically
|
||||
|
||||
- List what each role can currently reach, and confirm it still matches what that role's job requires.
|
||||
- Strip standing administrative access from roles that only need it occasionally - grant it temporarily instead.
|
||||
- Give administrators individual accounts rather than sharing one set of credentials.
|
||||
- Require MFA or security keys, at minimum for any role with elevated access.
|
||||
- Enforce session length and password rotation so old credentials don't quietly outlive their usefulness.
|
||||
- Enable device approvals for roles where an unrecognized device connecting should never happen silently.
|
||||
- Re-audit roles and their resource access on a recurring schedule, not just when something breaks.
|
||||
- Use rules, geo-blocking, and ASN blocking to shrink who can even attempt to authenticate in the first place.
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Users and Roles" icon="users" href="/manage/access-control/create-user">
|
||||
Group users into roles and control who belongs to each one.
|
||||
</Card>
|
||||
|
||||
<Card title="Resource Policies" icon="shield" href="/manage/resources/public/resource-policies">
|
||||
Define authentication and access rules once, reuse them everywhere.
|
||||
</Card>
|
||||
|
||||
<Card title="Rules" icon="filter" href="/manage/access-control/rules">
|
||||
Allow, deny, or require auth based on path, IP, country, or region.
|
||||
</Card>
|
||||
|
||||
<Card title="Device Approvals" icon="check" href="/manage/access-control/approvals">
|
||||
Require admin sign-off before a new device can connect.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
---
|
||||
title: "Pangolin Uses WireGuard"
|
||||
description: "How Pangolin uses WireGuard to create secure, encrypted connections"
|
||||
---
|
||||
|
||||
WireGuard is an open source network tunneling protocol for creating encrypted communication channels. It's designed to replace other VPN protocols, such as OpenVPN and IPsec, as a simpler and lighter-weight alternative. The protocol maintains concurrent connections with minimal overhead per session. Independent cryptographers have reviewed the WireGuard protocol, and security auditors have examined the code implementation, identifying and allowing for the correction of minor issues. For more about WireGuard's technical details, review their whitepaper.
|
||||
|
||||
Pangolin builds on top of WireGuard and adds additional components such as NAT traversal, relay fallback, and access control policies. Pangolin's implementation differs from standard WireGuard implementations in several ways. For example, where WireGuard provides encrypted tunnels between endpoints, Pangolin constructs a hub-and-spoke network topology with additional network services and authentication mechanisms. Pangolin uses the open source wireguard-go package running in userspace, which comes with Pangolin's Newt and Olm clients.
|
||||
@@ -0,0 +1,75 @@
|
||||
---
|
||||
title: "Zero Trust Networking"
|
||||
description: "Why Pangolin encrypts every connection and authorizes by identity rather than trusting the network it runs on."
|
||||
---
|
||||
|
||||
Zero trust networking starts from an uncomfortable assumption: the network your traffic physically travels over cannot be trusted, even the parts you think of as "internal." Access should be decided by who and what is asking, not by which wire or subnet the request happens to arrive on.
|
||||
|
||||
## Why the old assumption stopped holding
|
||||
|
||||
For a long time, network security was designed like a building: a hardened perimeter - the firewall - kept threats out, and everything inside that boundary was implicitly trusted. VPNs extended that same trusted interior out to remote workers. It's sometimes described as a hard shell around a soft interior.
|
||||
|
||||
That model breaks down once you account for how internal networks actually get compromised. Well-documented breaches at major technology companies have shown attackers reaching deep into "internal" infrastructure once they cleared the perimeter once. Add unencrypted internal DNS traffic and employees working from coffee shop Wi-Fi, and the idea that anything inside the firewall is automatically safe stops being credible. If the perimeter is the only thing enforcing security, one gap anywhere in it compromises everything behind it.
|
||||
|
||||
## What replaces trusting the wire
|
||||
|
||||
The fix is removing the network itself from the trust decision entirely:
|
||||
|
||||
- **Encrypt every connection, always**, regardless of whether the traffic is "internal" or "external." There's no privileged segment where encryption gets dropped because it's assumed to be safe.
|
||||
- **Authorize by identity, not location.** What a connection is allowed to reach should depend on who or what established it, not which subnet it originated from.
|
||||
- **Contain compromise at the peer.** If a device is breached, restricting which encrypted peers it's authorized to reach means the attacker can't simply pivot to whatever else happens to share that network segment.
|
||||
|
||||
Even if someone gains physical or logical access to the network itself, all they find is encrypted traffic between authorized peers - nothing to sniff, and no ability to move laterally without valid credentials of their own.
|
||||
|
||||
## How this shows up in Pangolin's architecture
|
||||
|
||||
Pangolin is built around this model rather than having it added on top:
|
||||
|
||||
- **Every tunnel is encrypted, by default, with no exceptions.** Site connectors and clients build their tunnels on WireGuard, coordinated by Pangolin's tunnel manager ([Gerbil](/development/system-architecture#nodes)) on the node side and the shared client stack ([Olm](/development/system-architecture#shared-client-stack-olm)) on the device side. There's no unencrypted "trusted internal" path anywhere in the data plane.
|
||||
- **Site connectors are deny-by-default proxies.** Installing a [site](/manage/sites/understanding-sites) doesn't expose anything on that network. Nothing is reachable until you explicitly define a [resource](/manage/resources/understanding-resources) and grant a role access to it - the network being reachable is never itself the authorization.
|
||||
- **Authentication happens per request, not per network.** Public resources are enforced through forward-auth middleware ([Badger](/development/system-architecture#nodes)) sitting in front of every request, and private resources are only reachable by clients that already hold a valid, role-scoped tunnel - being on the same LAN as a site connector grants nothing on its own.
|
||||
- **Access follows the user, not the connection point.** [Roles](/manage/access-control/create-user#roles) determine which resources a client is authorized to reach, and that access control list travels with the identity whether they're connecting from the office, home, or a coffee shop.
|
||||
|
||||
## Rolling this out without a flag day
|
||||
|
||||
You don't need to tear out your existing perimeter to start moving toward this model - it's meant to be adopted incrementally, service by service:
|
||||
|
||||
<Steps>
|
||||
<Step title="Wrap one sensitive service first">
|
||||
Stand up a [site](/manage/sites/install-site) alongside your existing network and turn a single high-value internal service into a [private resource](/manage/resources/understanding-resources#private-resource-types). Traffic to it is now encrypted end-to-end and gated by role, independent of whatever perimeter controls already exist.
|
||||
</Step>
|
||||
|
||||
<Step title="Verify access follows identity">
|
||||
Confirm that only the intended roles can reach the new resource, and that removing a role actually removes access - not just that the tunnel works.
|
||||
</Step>
|
||||
|
||||
<Step title="Repeat until the subnet is covered">
|
||||
Move the rest of the hosts behind that network into resources one at a time. Once everything on that subnet is reachable exclusively through Pangolin, the broader network-level trust it used to rely on (a VPN route, a wide firewall allowlist) is no longer load-bearing.
|
||||
</Step>
|
||||
|
||||
<Step title="Retire the old path and move to the next network">
|
||||
Remove the legacy access route for that subnet, then repeat the process for the next site or location.
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## What you still have to trust
|
||||
|
||||
"Zero trust" doesn't mean trusting nothing - it means narrowing what you trust down to a small, deliberate set of components: your identity provider, and the policy engine that decides who's authorized to reach what. In Pangolin, that's the [control plane](/development/system-architecture#control-plane) - the server that authenticates users, evaluates roles against resources, and pushes the resulting access decisions out to every node, site, and client. Everything else - the physical network, the datacenter, the office Wi-Fi - is treated as untrusted by design, which is precisely the point.
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="How Pangolin Works" icon="diagram-project" href="/about/how-pangolin-works">
|
||||
The product-level tour of sites, resources, and clients.
|
||||
</Card>
|
||||
|
||||
<Card title="System Architecture" icon="server" href="/development/system-architecture">
|
||||
A technical look at the control plane, nodes, connectors, and clients.
|
||||
</Card>
|
||||
|
||||
<Card title="Understanding Sites" icon="plug" href="/manage/sites/understanding-sites">
|
||||
How site connectors expose resources without opening inbound ports.
|
||||
</Card>
|
||||
|
||||
<Card title="Least-Privilege Access" icon="shield-halved" href="/about/security/least-privilege-access">
|
||||
Scoping who's authorized to reach what once identity is the boundary.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
@@ -30,7 +30,15 @@
|
||||
"about/how-pangolin-works",
|
||||
"about/pangolin-vs-reverse-proxy-vs-vpn",
|
||||
"about/pangolin-vs-bifrost-vs-litellm",
|
||||
"about/pangolin-cloud-vs-self-hosted"
|
||||
"about/pangolin-cloud-vs-self-hosted",
|
||||
{
|
||||
"group": "Security",
|
||||
"pages": [
|
||||
"about/security/zero-trust-networking",
|
||||
"about/security/least-privilege-access",
|
||||
"about/security/fips-fedramp"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -310,7 +310,7 @@ This section contains the complete reference for all configuration options in `c
|
||||
|
||||
**Default**: `false`
|
||||
|
||||
**Environment Variable**: `ENABLE_AI_GATEWAY_CLIENT_IP_HEADER` (or `ENABLE_AI_GATEWAY_CLIENT_IP_HEADER_FILE` to read the value from a file — see [Reading secrets from a file](#reading-secrets-from-a-file-_file-suffix))
|
||||
**Environment Variable**: `ENABLE_AI_GATEWAY_CLIENT_IP_HEADER` (or `ENABLE_AI_GATEWAY_CLIENT_IP_HEADER_FILE` to read the value from a file - see [Reading secrets from a file](#reading-secrets-from-a-file-_file-suffix))
|
||||
|
||||
<Note>
|
||||
Useful when an intermediary proxy sits between Traefik and the AI Gateway and overwrites `X-Forwarded-For`/`X-Real-Ip` instead of appending to them. Requires a Badger version that supports `realIpHeader`.
|
||||
@@ -336,7 +336,7 @@ This section contains the complete reference for all configuration options in `c
|
||||
<ResponseField name="secret" type="string" required>
|
||||
Secret key for encrypting sensitive data.
|
||||
|
||||
**Environment Variable**: `SERVER_SECRET` (or `SERVER_SECRET_FILE` to read the value from a file — see [Reading secrets from a file](#reading-secrets-from-a-file-_file-suffix))
|
||||
**Environment Variable**: `SERVER_SECRET` (or `SERVER_SECRET_FILE` to read the value from a file - see [Reading secrets from a file](#reading-secrets-from-a-file-_file-suffix))
|
||||
|
||||
**Minimum Length**: 8 characters
|
||||
|
||||
@@ -765,7 +765,7 @@ This section contains the complete reference for all configuration options in `c
|
||||
<ResponseField name="smtp_user" type="string">
|
||||
SMTP username.
|
||||
|
||||
**Environment Variable**: `EMAIL_SMTP_USER` (or `EMAIL_SMTP_USER_FILE` to read the value from a file — see [Reading secrets from a file](#reading-secrets-from-a-file-_file-suffix))
|
||||
**Environment Variable**: `EMAIL_SMTP_USER` (or `EMAIL_SMTP_USER_FILE` to read the value from a file - see [Reading secrets from a file](#reading-secrets-from-a-file-_file-suffix))
|
||||
|
||||
**Example**: `no-reply@example.com`
|
||||
</ResponseField>
|
||||
@@ -773,7 +773,7 @@ This section contains the complete reference for all configuration options in `c
|
||||
<ResponseField name="smtp_pass" type="string">
|
||||
SMTP password.
|
||||
|
||||
**Environment Variable**: `EMAIL_SMTP_PASS` (or `EMAIL_SMTP_PASS_FILE` to read the value from a file — see [Reading secrets from a file](#reading-secrets-from-a-file-_file-suffix))
|
||||
**Environment Variable**: `EMAIL_SMTP_PASS` (or `EMAIL_SMTP_PASS_FILE` to read the value from a file - see [Reading secrets from a file](#reading-secrets-from-a-file-_file-suffix))
|
||||
</ResponseField>
|
||||
|
||||
<ResponseField name="smtp_secure" type="boolean">
|
||||
@@ -938,7 +938,7 @@ This section contains the complete reference for all configuration options in `c
|
||||
<ResponseField name="connection_string" type="string" required>
|
||||
PostgreSQL connection string.
|
||||
|
||||
**Environment Variable**: `POSTGRES_CONNECTION_STRING` (or `POSTGRES_CONNECTION_STRING_FILE` to read the value from a file — see [Reading secrets from a file](#reading-secrets-from-a-file-_file-suffix))
|
||||
**Environment Variable**: `POSTGRES_CONNECTION_STRING` (or `POSTGRES_CONNECTION_STRING_FILE` to read the value from a file - see [Reading secrets from a file](#reading-secrets-from-a-file-_file-suffix))
|
||||
|
||||
**Example**: `postgresql://user:password@host:port/database`
|
||||
|
||||
@@ -950,7 +950,7 @@ This section contains the complete reference for all configuration options in `c
|
||||
<ResponseField name="replicas" type="array of objects">
|
||||
Read-only replica database configurations for load balancing.
|
||||
|
||||
**Environment Variable**: `POSTGRES_REPLICA_CONNECTION_STRINGS`, a comma-separated list of connection strings (or `POSTGRES_REPLICA_CONNECTION_STRINGS_FILE` to read the same comma-separated list from a file — see [Reading secrets from a file](#reading-secrets-from-a-file-_file-suffix))
|
||||
**Environment Variable**: `POSTGRES_REPLICA_CONNECTION_STRINGS`, a comma-separated list of connection strings (or `POSTGRES_REPLICA_CONNECTION_STRINGS_FILE` to read the same comma-separated list from a file - see [Reading secrets from a file](#reading-secrets-from-a-file-_file-suffix))
|
||||
|
||||
<Expandable title="Replica Configuration">
|
||||
<ResponseField name="connection_string" type="string" required>
|
||||
@@ -1020,7 +1020,7 @@ This section contains the complete reference for all configuration options in `c
|
||||
<ResponseField name="connection_string" type="string">
|
||||
Connection string for the dedicated logs database.
|
||||
|
||||
**Environment Variable**: `POSTGRES_LOGS_CONNECTION_STRING` (or `POSTGRES_LOGS_CONNECTION_STRING_FILE` to read the value from a file — see [Reading secrets from a file](#reading-secrets-from-a-file-_file-suffix))
|
||||
**Environment Variable**: `POSTGRES_LOGS_CONNECTION_STRING` (or `POSTGRES_LOGS_CONNECTION_STRING_FILE` to read the value from a file - see [Reading secrets from a file](#reading-secrets-from-a-file-_file-suffix))
|
||||
|
||||
**Example**: `postgresql://user:password@host:port/logs_database`
|
||||
|
||||
@@ -1032,7 +1032,7 @@ This section contains the complete reference for all configuration options in `c
|
||||
<ResponseField name="replicas" type="array of objects">
|
||||
Read-only replica configurations for the logs database.
|
||||
|
||||
**Environment Variable**: `POSTGRES_LOGS_REPLICA_CONNECTION_STRINGS`, a comma-separated list of connection strings (or `POSTGRES_LOGS_REPLICA_CONNECTION_STRINGS_FILE` to read the same comma-separated list from a file — see [Reading secrets from a file](#reading-secrets-from-a-file-_file-suffix))
|
||||
**Environment Variable**: `POSTGRES_LOGS_REPLICA_CONNECTION_STRINGS`, a comma-separated list of connection strings (or `POSTGRES_LOGS_REPLICA_CONNECTION_STRINGS_FILE` to read the same comma-separated list from a file - see [Reading secrets from a file](#reading-secrets-from-a-file-_file-suffix))
|
||||
|
||||
<Expandable title="Replica Configuration">
|
||||
<ResponseField name="connection_string" type="string" required>
|
||||
@@ -1199,7 +1199,7 @@ Some configuration values can be set using environment variables for enhanced se
|
||||
|
||||
### Reading secrets from a file (`_FILE` suffix)
|
||||
|
||||
For any variable marked "Supports `_FILE`" above, you can set `<VARIABLE>_FILE` instead of `<VARIABLE>` to a path on disk, and Pangolin will read that file and use its (trimmed) contents as the value. This is the standard way to consume [Docker/Swarm secrets](https://docs.docker.com/engine/swarm/secrets/) — for example a secret mounted at `/run/secrets/server_secret` — without ever putting the raw value in `config.yml`, a `.env` file, or the container's visible environment.
|
||||
For any variable marked "Supports `_FILE`" above, you can set `<VARIABLE>_FILE` instead of `<VARIABLE>` to a path on disk, and Pangolin will read that file and use its (trimmed) contents as the value. This is the standard way to consume [Docker/Swarm secrets](https://docs.docker.com/engine/swarm/secrets/) - for example a secret mounted at `/run/secrets/server_secret` - without ever putting the raw value in `config.yml`, a `.env` file, or the container's visible environment.
|
||||
|
||||
Setting both `<VARIABLE>` and `<VARIABLE>_FILE` at the same time is an error.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user