mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-04 16:26:16 +00:00
misc: addressed comments
This commit is contained in:
@@ -4,6 +4,7 @@ import { getConfig } from "@app/lib/config/env";
|
|||||||
import { crypto } from "@app/lib/crypto/cryptography";
|
import { crypto } from "@app/lib/crypto/cryptography";
|
||||||
import { BadRequestError, UnauthorizedError } from "@app/lib/errors";
|
import { BadRequestError, UnauthorizedError } from "@app/lib/errors";
|
||||||
import { writeLimit } from "@app/server/config/rateLimiter";
|
import { writeLimit } from "@app/server/config/rateLimiter";
|
||||||
|
import { slugSchema } from "@app/server/lib/schemas";
|
||||||
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
||||||
import { AuthMode } from "@app/services/auth/auth-type";
|
import { AuthMode } from "@app/services/auth/auth-type";
|
||||||
|
|
||||||
@@ -19,7 +20,7 @@ export const registerRelayRouter = async (server: FastifyZodProvider) => {
|
|||||||
schema: {
|
schema: {
|
||||||
body: z.object({
|
body: z.object({
|
||||||
host: z.string(),
|
host: z.string(),
|
||||||
name: z.string()
|
name: slugSchema({ min: 1, max: 32, field: "name" })
|
||||||
}),
|
}),
|
||||||
response: {
|
response: {
|
||||||
200: z.object({
|
200: z.object({
|
||||||
@@ -69,7 +70,7 @@ export const registerRelayRouter = async (server: FastifyZodProvider) => {
|
|||||||
schema: {
|
schema: {
|
||||||
body: z.object({
|
body: z.object({
|
||||||
host: z.string(),
|
host: z.string(),
|
||||||
name: z.string()
|
name: slugSchema({ min: 1, max: 32, field: "name" })
|
||||||
}),
|
}),
|
||||||
response: {
|
response: {
|
||||||
200: z.object({
|
200: z.object({
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import z from "zod";
|
|||||||
|
|
||||||
import { GatewaysV2Schema } from "@app/db/schemas";
|
import { GatewaysV2Schema } from "@app/db/schemas";
|
||||||
import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
|
import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
|
||||||
|
import { slugSchema } from "@app/server/lib/schemas";
|
||||||
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
||||||
import { AuthMode } from "@app/services/auth/auth-type";
|
import { AuthMode } from "@app/services/auth/auth-type";
|
||||||
|
|
||||||
@@ -20,8 +21,8 @@ export const registerGatewayV2Router = async (server: FastifyZodProvider) => {
|
|||||||
url: "/",
|
url: "/",
|
||||||
schema: {
|
schema: {
|
||||||
body: z.object({
|
body: z.object({
|
||||||
relayName: z.string(),
|
relayName: slugSchema({ min: 1, max: 32, field: "relayName" }),
|
||||||
name: z.string()
|
name: slugSchema({ min: 1, max: 32, field: "name" })
|
||||||
}),
|
}),
|
||||||
response: {
|
response: {
|
||||||
200: z.object({
|
200: z.object({
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { Knex } from "knex";
|
||||||
|
|
||||||
import { TDbClient } from "@app/db";
|
import { TDbClient } from "@app/db";
|
||||||
import { GatewaysV2Schema, TableName, TGatewaysV2 } from "@app/db/schemas";
|
import { GatewaysV2Schema, TableName, TGatewaysV2 } from "@app/db/schemas";
|
||||||
import { DatabaseError } from "@app/lib/errors";
|
import { DatabaseError } from "@app/lib/errors";
|
||||||
@@ -10,7 +12,7 @@ export const gatewayV2DalFactory = (db: TDbClient) => {
|
|||||||
|
|
||||||
const find = async (filter: TFindFilter<TGatewaysV2>, { offset, limit, sort, tx }: TFindOpt<TGatewaysV2> = {}) => {
|
const find = async (filter: TFindFilter<TGatewaysV2>, { offset, limit, sort, tx }: TFindOpt<TGatewaysV2> = {}) => {
|
||||||
try {
|
try {
|
||||||
const query = (tx || db)(TableName.GatewayV2)
|
const query = (tx || db.replicaNode())(TableName.GatewayV2)
|
||||||
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
||||||
.where(buildFindFilter(filter, TableName.GatewayV2))
|
.where(buildFindFilter(filter, TableName.GatewayV2))
|
||||||
.join(TableName.Identity, `${TableName.Identity}.id`, `${TableName.GatewayV2}.identityId`)
|
.join(TableName.Identity, `${TableName.Identity}.id`, `${TableName.GatewayV2}.identityId`)
|
||||||
@@ -39,5 +41,20 @@ export const gatewayV2DalFactory = (db: TDbClient) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return { ...orm, find };
|
const findById = async (id: string, tx?: Knex) => {
|
||||||
|
try {
|
||||||
|
const doc = await (tx || db.replicaNode())(TableName.GatewayV2)
|
||||||
|
.join(TableName.Organization, `${TableName.GatewayV2}.orgId`, `${TableName.Organization}.id`)
|
||||||
|
.where(`${TableName.GatewayV2}.id`, id)
|
||||||
|
.select(selectAllTableCols(TableName.GatewayV2))
|
||||||
|
.select(db.ref("name").withSchema(TableName.Organization).as("orgName"))
|
||||||
|
.first();
|
||||||
|
|
||||||
|
return doc;
|
||||||
|
} catch (error) {
|
||||||
|
throw new DatabaseError({ error, name: `${TableName.GatewayV2}: Find by id` });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return { ...orm, find, findById };
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -394,6 +394,7 @@ export const gatewayV2ServiceFactory = ({
|
|||||||
const relayCredentials = await relayService.getCredentialsForClient({
|
const relayCredentials = await relayService.getCredentialsForClient({
|
||||||
relayId: gateway.relayId,
|
relayId: gateway.relayId,
|
||||||
orgId: gateway.orgId,
|
orgId: gateway.orgId,
|
||||||
|
orgName: gateway.orgName,
|
||||||
gatewayId
|
gatewayId
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import {
|
|||||||
import { TKmsServiceFactory } from "@app/services/kms/kms-service";
|
import { TKmsServiceFactory } from "@app/services/kms/kms-service";
|
||||||
import { KmsDataKey } from "@app/services/kms/kms-types";
|
import { KmsDataKey } from "@app/services/kms/kms-types";
|
||||||
|
|
||||||
|
import { verifyHostInputValidity } from "../dynamic-secret/dynamic-secret-fns";
|
||||||
import { createSshCert, createSshKeyPair } from "../ssh/ssh-certificate-authority-fns";
|
import { createSshCert, createSshKeyPair } from "../ssh/ssh-certificate-authority-fns";
|
||||||
import { SshCertType } from "../ssh/ssh-certificate-authority-types";
|
import { SshCertType } from "../ssh/ssh-certificate-authority-types";
|
||||||
import { SshCertKeyAlgorithm } from "../ssh-certificate/ssh-certificate-types";
|
import { SshCertKeyAlgorithm } from "../ssh-certificate/ssh-certificate-types";
|
||||||
@@ -689,6 +690,7 @@ export const relayServiceFactory = ({
|
|||||||
const $generateRelayClientCredentials = async ({
|
const $generateRelayClientCredentials = async ({
|
||||||
gatewayId,
|
gatewayId,
|
||||||
orgId,
|
orgId,
|
||||||
|
orgName,
|
||||||
relayPkiClientCaCertificate,
|
relayPkiClientCaCertificate,
|
||||||
relayPkiClientCaPrivateKey,
|
relayPkiClientCaPrivateKey,
|
||||||
relayPkiServerCaCertificate,
|
relayPkiServerCaCertificate,
|
||||||
@@ -696,6 +698,7 @@ export const relayServiceFactory = ({
|
|||||||
}: {
|
}: {
|
||||||
gatewayId: string;
|
gatewayId: string;
|
||||||
orgId: string;
|
orgId: string;
|
||||||
|
orgName: string;
|
||||||
relayPkiClientCaCertificate: Buffer;
|
relayPkiClientCaCertificate: Buffer;
|
||||||
relayPkiClientCaPrivateKey: Buffer;
|
relayPkiClientCaPrivateKey: Buffer;
|
||||||
relayPkiServerCaCertificate: Buffer;
|
relayPkiServerCaCertificate: Buffer;
|
||||||
@@ -742,7 +745,7 @@ export const relayServiceFactory = ({
|
|||||||
|
|
||||||
const clientCert = await x509.X509CertificateGenerator.create({
|
const clientCert = await x509.X509CertificateGenerator.create({
|
||||||
serialNumber: clientCertSerialNumber,
|
serialNumber: clientCertSerialNumber,
|
||||||
subject: `O=${orgId},OU=relay-client,CN=${gatewayId}`,
|
subject: `O=${orgName}-${orgId},OU=relay-client,CN=${gatewayId}`,
|
||||||
issuer: relayClientCaCert.subject,
|
issuer: relayClientCaCert.subject,
|
||||||
notAfter: clientCertExpiration,
|
notAfter: clientCertExpiration,
|
||||||
notBefore: clientCertIssuedAt,
|
notBefore: clientCertIssuedAt,
|
||||||
@@ -833,10 +836,12 @@ export const relayServiceFactory = ({
|
|||||||
const getCredentialsForClient = async ({
|
const getCredentialsForClient = async ({
|
||||||
relayId,
|
relayId,
|
||||||
orgId,
|
orgId,
|
||||||
|
orgName,
|
||||||
gatewayId
|
gatewayId
|
||||||
}: {
|
}: {
|
||||||
relayId: string;
|
relayId: string;
|
||||||
orgId: string;
|
orgId: string;
|
||||||
|
orgName: string;
|
||||||
gatewayId: string;
|
gatewayId: string;
|
||||||
}) => {
|
}) => {
|
||||||
const relay = await relayDAL.findOne({
|
const relay = await relayDAL.findOne({
|
||||||
@@ -849,11 +854,14 @@ export const relayServiceFactory = ({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await verifyHostInputValidity(relay.host);
|
||||||
|
|
||||||
if (relay.orgId === null) {
|
if (relay.orgId === null) {
|
||||||
const instanceCAs = await $getInstanceCAs();
|
const instanceCAs = await $getInstanceCAs();
|
||||||
const relayCertificateCredentials = await $generateRelayClientCredentials({
|
const relayCertificateCredentials = await $generateRelayClientCredentials({
|
||||||
gatewayId,
|
gatewayId,
|
||||||
orgId,
|
orgId,
|
||||||
|
orgName,
|
||||||
relayPkiClientCaCertificate: instanceCAs.instanceRelayPkiClientCaCertificate,
|
relayPkiClientCaCertificate: instanceCAs.instanceRelayPkiClientCaCertificate,
|
||||||
relayPkiClientCaPrivateKey: instanceCAs.instanceRelayPkiClientCaPrivateKey,
|
relayPkiClientCaPrivateKey: instanceCAs.instanceRelayPkiClientCaPrivateKey,
|
||||||
relayPkiServerCaCertificate: instanceCAs.instanceRelayPkiServerCaCertificate,
|
relayPkiServerCaCertificate: instanceCAs.instanceRelayPkiServerCaCertificate,
|
||||||
@@ -870,6 +878,7 @@ export const relayServiceFactory = ({
|
|||||||
const relayCertificateCredentials = await $generateRelayClientCredentials({
|
const relayCertificateCredentials = await $generateRelayClientCredentials({
|
||||||
gatewayId,
|
gatewayId,
|
||||||
orgId,
|
orgId,
|
||||||
|
orgName,
|
||||||
relayPkiClientCaCertificate: orgCAs.relayPkiClientCaCertificate,
|
relayPkiClientCaCertificate: orgCAs.relayPkiClientCaCertificate,
|
||||||
relayPkiClientCaPrivateKey: orgCAs.relayPkiClientCaPrivateKey,
|
relayPkiClientCaPrivateKey: orgCAs.relayPkiClientCaPrivateKey,
|
||||||
relayPkiServerCaCertificate: orgCAs.relayPkiServerCaCertificate,
|
relayPkiServerCaCertificate: orgCAs.relayPkiServerCaCertificate,
|
||||||
@@ -896,6 +905,8 @@ export const relayServiceFactory = ({
|
|||||||
let relay: TRelays;
|
let relay: TRelays;
|
||||||
const isOrgRelay = identityId && orgId;
|
const isOrgRelay = identityId && orgId;
|
||||||
|
|
||||||
|
await verifyHostInputValidity(host);
|
||||||
|
|
||||||
if (isOrgRelay) {
|
if (isOrgRelay) {
|
||||||
relay = await relayDAL.transaction(async (tx) => {
|
relay = await relayDAL.transaction(async (tx) => {
|
||||||
const existingRelay = await relayDAL.findOne(
|
const existingRelay = await relayDAL.findOne(
|
||||||
@@ -907,9 +918,7 @@ export const relayServiceFactory = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (existingRelay && (existingRelay.host !== host || existingRelay.name !== name)) {
|
if (existingRelay && (existingRelay.host !== host || existingRelay.name !== name)) {
|
||||||
throw new BadRequestError({
|
return relayDAL.updateById(existingRelay.id, { host, name }, tx);
|
||||||
message: "Org relay with this machine identity already exists."
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!existingRelay) {
|
if (!existingRelay) {
|
||||||
@@ -937,9 +946,7 @@ export const relayServiceFactory = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (existingRelay && existingRelay.host !== host) {
|
if (existingRelay && existingRelay.host !== host) {
|
||||||
throw new BadRequestError({
|
return relayDAL.updateById(existingRelay.id, { host }, tx);
|
||||||
message: "Instance relay with this name already exists with a different host"
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!existingRelay) {
|
if (!existingRelay) {
|
||||||
|
|||||||
@@ -22,6 +22,13 @@ The Infisical gateway provides secure access to private resources using modern T
|
|||||||
|
|
||||||
The gateway system uses SSH reverse tunnels over TCP, eliminating firewall complexity and providing excellent performance for enterprise environments.
|
The gateway system uses SSH reverse tunnels over TCP, eliminating firewall complexity and providing excellent performance for enterprise environments.
|
||||||
|
|
||||||
|
<Warning>
|
||||||
|
**Deprecation and Migration Notice:** The legacy `infisical gateway` command (v1) will be removed in a future release. Please migrate to `infisical gateway start` (Gateway v2).
|
||||||
|
|
||||||
|
If you are moving from Gateway v1 to Gateway v2, this is NOT a drop-in switch. Gateway v2 creates new gateway instances with new gateway IDs. You must update any existing resources that reference gateway IDs (for example: dynamic secret configs, app connections, or other gateway-bound resources) to point to the new Gateway v2 gateway ID. Until you update those references, traffic will continue to target the old v1 gateway.
|
||||||
|
|
||||||
|
</Warning>
|
||||||
|
|
||||||
## Subcommands & flags
|
## Subcommands & flags
|
||||||
|
|
||||||
<Accordion title="infisical gateway start" defaultOpen="true">
|
<Accordion title="infisical gateway start" defaultOpen="true">
|
||||||
@@ -361,6 +368,9 @@ sudo systemctl disable infisical-gateway # Disable auto-start on boot
|
|||||||
**This command is deprecated and will be removed in a future release.**
|
**This command is deprecated and will be removed in a future release.**
|
||||||
|
|
||||||
Please migrate to `infisical gateway start` for the new TCP-based SSH tunnel architecture.
|
Please migrate to `infisical gateway start` for the new TCP-based SSH tunnel architecture.
|
||||||
|
|
||||||
|
**Migration required:** If you are currently using Gateway v1 (via `infisical gateway`), moving to Gateway v2 is not in-place. Gateway v2 provisions new gateway instances with new gateway IDs. Update any resources that reference a gateway ID (for example: dynamic secret configs, app connections, or other gateway-bound resources) to use the new Gateway v2 gateway ID. Until you update those references, traffic will continue to target the old v1 gateway.
|
||||||
|
|
||||||
</Warning>
|
</Warning>
|
||||||
|
|
||||||
Run the legacy Infisical gateway in the foreground. The gateway will connect to the relay service and maintain a persistent connection.
|
Run the legacy Infisical gateway in the foreground. The gateway will connect to the relay service and maintain a persistent connection.
|
||||||
@@ -585,6 +595,9 @@ The Infisical CLI supports multiple authentication methods. Below are the availa
|
|||||||
**This command is deprecated and will be removed in a future release.**
|
**This command is deprecated and will be removed in a future release.**
|
||||||
|
|
||||||
Please migrate to `infisical gateway systemd install` for the new TCP-based SSH tunnel architecture with enhanced security and better performance.
|
Please migrate to `infisical gateway systemd install` for the new TCP-based SSH tunnel architecture with enhanced security and better performance.
|
||||||
|
|
||||||
|
**Migration required:** If you previously installed Gateway v1 via `infisical gateway install`, moving to Gateway v2 is not in-place. Gateway v2 provisions new gateway instances with new gateway IDs. Update any resources that reference a gateway ID (for example: dynamic secret configs, app connections, or other gateway-bound resources) to use the new Gateway v2 gateway ID. Until you update those references, traffic will continue to target the old v1 gateway.
|
||||||
|
|
||||||
</Warning>
|
</Warning>
|
||||||
|
|
||||||
Install and enable the legacy gateway as a systemd service. This command must be run with sudo on Linux.
|
Install and enable the legacy gateway as a systemd service. This command must be run with sudo on Linux.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
title: "infisical relay"
|
title: "infisical relay"
|
||||||
description: "Relay-related commands for Infisical including proxy components"
|
description: "Relay-related commands for Infisical"
|
||||||
---
|
---
|
||||||
|
|
||||||
<Tabs>
|
<Tabs>
|
||||||
@@ -33,7 +33,7 @@ infisical relay start --type=<type> --host=<host> --name=<name> --auth-method=<a
|
|||||||
<Accordion title="--type">
|
<Accordion title="--type">
|
||||||
The type of relay to run. Must be either 'instance' or 'org'.
|
The type of relay to run. Must be either 'instance' or 'org'.
|
||||||
|
|
||||||
- **`instance`**: Shared relay server that can be used by all organizations on your Infisical instance. Set up by the instance administrator. Uses `INFISICAL_PROXY_AUTH_SECRET` environment variable for authentication, which must be configured by the instance admin.
|
- **`instance`**: Shared relay server that can be used by all organizations on your Infisical instance. Set up by the instance administrator. Uses `INFISICAL_RELAY_AUTH_SECRET` environment variable for authentication, which must be configured by the instance admin.
|
||||||
- **`org`**: Dedicated relay server that individual organizations deploy and manage in their own infrastructure. Provides enhanced security, custom geographic placement, and compliance benefits. Uses standard Infisical authentication methods.
|
- **`org`**: Dedicated relay server that individual organizations deploy and manage in their own infrastructure. Provides enhanced security, custom geographic placement, and compliance benefits. Uses standard Infisical authentication methods.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -41,7 +41,7 @@ infisical relay start --type=<type> --host=<host> --name=<name> --auth-method=<a
|
|||||||
infisical relay start --type=org --host=192.168.1.100 --name=my-org-relay
|
infisical relay start --type=org --host=192.168.1.100 --name=my-org-relay
|
||||||
|
|
||||||
# Instance relay (configured by instance admin)
|
# Instance relay (configured by instance admin)
|
||||||
INFISICAL_PROXY_AUTH_SECRET=<secret> infisical relay start --type=instance --host=10.0.1.50 --name=shared-relay
|
INFISICAL_RELAY_AUTH_SECRET=<secret> infisical relay start --type=instance --host=10.0.1.50 --name=shared-relay
|
||||||
```
|
```
|
||||||
|
|
||||||
</Accordion>
|
</Accordion>
|
||||||
@@ -75,14 +75,14 @@ infisical relay start --type=<type> --host=<host> --name=<name> --auth-method=<a
|
|||||||
Deploy your own relay server in your infrastructure for enhanced security and reduced latency. Supports all standard Infisical authentication methods documented below.
|
Deploy your own relay server in your infrastructure for enhanced security and reduced latency. Supports all standard Infisical authentication methods documented below.
|
||||||
|
|
||||||
**Instance Relays (`--type=instance`):**
|
**Instance Relays (`--type=instance`):**
|
||||||
Shared relay servers that serve all organizations on your Infisical instance. For Infisical Cloud, these are already running and ready to use. For self-hosted deployments, they're set up by the instance administrator. Authentication is handled via the `INFISICAL_PROXY_AUTH_SECRET` environment variable.
|
Shared relay servers that serve all organizations on your Infisical instance. For Infisical Cloud, these are already running and ready to use. For self-hosted deployments, they're set up by the instance administrator. Authentication is handled via the `INFISICAL_RELAY_AUTH_SECRET` environment variable.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Organization relay with Universal Auth (customer-deployed)
|
# Organization relay with Universal Auth (customer-deployed)
|
||||||
infisical relay start --type=org --host=192.168.1.100 --name=my-org-relay --auth-method=universal-auth --client-id=<client-id> --client-secret=<client-secret>
|
infisical relay start --type=org --host=192.168.1.100 --name=my-org-relay --auth-method=universal-auth --client-id=<client-id> --client-secret=<client-secret>
|
||||||
|
|
||||||
# Instance relay (configured by instance admin)
|
# Instance relay (configured by instance admin)
|
||||||
INFISICAL_PROXY_AUTH_SECRET=<secret> infisical relay start --type=instance --host=10.0.1.50 --name=shared-relay
|
INFISICAL_RELAY_AUTH_SECRET=<secret> infisical relay start --type=instance --host=10.0.1.50 --name=shared-relay
|
||||||
```
|
```
|
||||||
|
|
||||||
### Authentication Methods
|
### Authentication Methods
|
||||||
|
|||||||
@@ -68,26 +68,35 @@ Gateway ↔ Relay Server communication uses SSH certificate authentication:
|
|||||||
- Gateway validates certificate against appropriate SSH Server CA
|
- Gateway validates certificate against appropriate SSH Server CA
|
||||||
- Ensures gateway connects to legitimate relay infrastructure
|
- Ensures gateway connects to legitimate relay infrastructure
|
||||||
|
|
||||||
### 3. Application Traffic Security
|
### 3. Platform-to-Gateway Direct Connection
|
||||||
|
|
||||||
End-to-end encryption for application data:
|
The platform establishes secure direct connections with gateways through a **TLS-pinned tunnel** mechanism:
|
||||||
|
|
||||||
1. **mTLS Layer**:
|
1. **TLS-Pinned Tunnel Establishment**:
|
||||||
|
|
||||||
- Infisical platform establishes mTLS connections directly with gateways
|
- Gateway initiates outbound connection to platform through SSH reverse tunnel
|
||||||
- Uses Organization Gateway certificates for authentication
|
- Platform establishes direct mTLS connection with gateway using Organization Gateway certificates
|
||||||
- Application traffic is encrypted end-to-end between platform and gateway
|
- TLS certificate pinning ensures the connection is bound to the specific gateway identity
|
||||||
|
- No inbound connections required - all communication flows through the outbound tunnel
|
||||||
|
|
||||||
2. **SSH Tunnel Layer**:
|
2. **Connection Flow**:
|
||||||
|
|
||||||
- mTLS-encrypted application traffic travels through SSH reverse tunnels
|
```
|
||||||
- Creates double encryption: mTLS payload within SSH tunnel
|
Platform ←→ [SSH Reverse Tunnel] ←→ Gateway
|
||||||
- Relay servers cannot decrypt either encryption layer
|
```
|
||||||
|
|
||||||
3. **Traffic Isolation**:
|
- Gateway maintains persistent outbound SSH tunnel to relay server
|
||||||
- Each gateway maintains separate SSH tunnels
|
- Platform connects directly to gateway through this tunnel
|
||||||
- Organization's private keys never leave their environment
|
- TLS handshake occurs over the SSH tunnel, establishing mTLS connection
|
||||||
- Complete cryptographic isolation between organizations
|
- Application traffic flows through the TLS-pinned tunnel
|
||||||
|
|
||||||
|
3. **Security Benefits**:
|
||||||
|
|
||||||
|
- **No inbound connections**: Gateway never needs to accept incoming connections
|
||||||
|
- **Certificate-based authentication**: Uses Organization Gateway certificates for mutual TLS
|
||||||
|
- **Double encryption**: TLS traffic within SSH tunnel provides layered security
|
||||||
|
- **Relay server isolation**: Relay cannot decrypt either TLS or application data
|
||||||
|
- **Tenant isolation**: Each organization's traffic flows through separate authenticated channels
|
||||||
|
|
||||||
## Tenant Isolation
|
## Tenant Isolation
|
||||||
|
|
||||||
|
|||||||
@@ -102,6 +102,13 @@ Once authenticated, the Gateway establishes an SSH reverse tunnel to the specifi
|
|||||||
<Tabs>
|
<Tabs>
|
||||||
<Tab title="Production (systemd)">
|
<Tab title="Production (systemd)">
|
||||||
For production deployments on Linux, install the Gateway as a systemd service:
|
For production deployments on Linux, install the Gateway as a systemd service:
|
||||||
|
|
||||||
|
<Warning>
|
||||||
|
**Gateway v2:** The `infisical gateway systemd install` command deploys the new Gateway v2 component.
|
||||||
|
|
||||||
|
If you are migrating from Gateway v1 (legacy `infisical gateway install` command), this is not in-place. Gateway v2 provisions new gateway instances with new gateway IDs. Update any resources that reference a gateway ID (for example: dynamic secret configs, app connections, or other gateway-bound resources) to use the new Gateway v2 gateway ID.
|
||||||
|
</Warning>
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo infisical gateway systemd install --token <your-machine-identity-token> --domain <your-infisical-domain> --name <gateway-name> --relay <relay-name>
|
sudo infisical gateway systemd install --token <your-machine-identity-token> --domain <your-infisical-domain> --name <gateway-name> --relay <relay-name>
|
||||||
sudo systemctl start infisical-gateway
|
sudo systemctl start infisical-gateway
|
||||||
@@ -369,8 +376,13 @@ Once authenticated, the Gateway establishes an SSH reverse tunnel to the specifi
|
|||||||
</Accordion>
|
</Accordion>
|
||||||
</AccordionGroup>
|
</AccordionGroup>
|
||||||
|
|
||||||
|
|
||||||
### Install the Infisical Gateway Helm Chart
|
### Install the Infisical Gateway Helm Chart
|
||||||
|
<Warning>
|
||||||
|
**Version mapping:** Helm chart versions `>= 1.0.0` contain the new Gateway v2 component. Helm chart versions `<= 0.0.5` contain the legacy Gateway v1 component.
|
||||||
|
|
||||||
|
If you are moving from Gateway v1 (chart `<= 0.0.5`) to Gateway v2 (chart `>= 1.0.0`), this is not in-place. Gateway v2 provisions new gateway instances with new gateway IDs. Update any resources that reference a gateway ID (for example: dynamic secret configs, app connections, or other gateway-bound resources) to use the new Gateway v2 gateway ID.
|
||||||
|
</Warning>
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
helm install infisical-gateway infisical-helm-charts/infisical-gateway
|
helm install infisical-gateway infisical-helm-charts/infisical-gateway
|
||||||
```
|
```
|
||||||
@@ -385,11 +397,17 @@ Once authenticated, the Gateway establishes an SSH reverse tunnel to the specifi
|
|||||||
You should see the following output which indicates the gateway is running as expected.
|
You should see the following output which indicates the gateway is running as expected.
|
||||||
```bash
|
```bash
|
||||||
$ kubectl logs deployment/infisical-gateway
|
$ kubectl logs deployment/infisical-gateway
|
||||||
INF Starting gateway
|
12:43AM INF Starting gateway
|
||||||
INF Starting gateway certificate renewal goroutine
|
12:43AM INF Starting gateway certificate renewal goroutine
|
||||||
INF Successfully registered gateway and received certificates
|
12:43AM INF Successfully registered gateway and received certificates
|
||||||
INF Connecting to relay server infisical-start on 152.42.218.156:2222...
|
12:43AM INF Connecting to relay server infisical-start on 152.42.218.156:2222...
|
||||||
INF Relay connection established for gateway
|
12:43AM INF Relay connection established for gateway
|
||||||
|
12:43AM INF Received incoming connection, starting TLS handshake
|
||||||
|
12:43AM INF TLS handshake completed successfully
|
||||||
|
12:43AM INF Negotiated ALPN protocol: infisical-ping
|
||||||
|
12:43AM INF Starting ping handler
|
||||||
|
12:43AM INF Ping handler completed
|
||||||
|
12:43AM INF Gateway is reachable by Infisical
|
||||||
```
|
```
|
||||||
|
|
||||||
</Tab>
|
</Tab>
|
||||||
|
|||||||
Reference in New Issue
Block a user