misc: addressed comments

This commit is contained in:
Sheen Capadngan
2025-09-09 03:42:52 +08:00
parent b7dcc10731
commit 18398457e0
14 changed files with 99 additions and 110 deletions
@@ -98,8 +98,10 @@ export async function up(knex: Knex): Promise<void> {
t.uuid("identityId"); t.uuid("identityId");
t.foreign("identityId").references("id").inTable(TableName.Identity).onDelete("CASCADE"); t.foreign("identityId").references("id").inTable(TableName.Identity).onDelete("CASCADE");
t.string("name").notNullable().unique(); t.string("name").notNullable();
t.string("ip").notNullable(); t.string("host").notNullable();
t.unique(["orgId", "name"]);
}); });
await createOnUpdateTrigger(knex, TableName.Relay); await createOnUpdateTrigger(knex, TableName.Relay);
@@ -119,7 +121,9 @@ export async function up(knex: Knex): Promise<void> {
t.uuid("relayId"); t.uuid("relayId");
t.foreign("relayId").references("id").inTable(TableName.Relay).onDelete("SET NULL"); t.foreign("relayId").references("id").inTable(TableName.Relay).onDelete("SET NULL");
t.string("name").notNullable().unique(); t.string("name").notNullable();
t.unique(["orgId", "name"]);
t.dateTime("heartbeat"); t.dateTime("heartbeat");
}); });
+1 -1
View File
@@ -14,7 +14,7 @@ export const RelaysSchema = z.object({
orgId: z.string().uuid().nullable().optional(), orgId: z.string().uuid().nullable().optional(),
identityId: z.string().uuid().nullable().optional(), identityId: z.string().uuid().nullable().optional(),
name: z.string(), name: z.string(),
ip: z.string() host: z.string()
}); });
export type TRelays = z.infer<typeof RelaysSchema>; export type TRelays = z.infer<typeof RelaysSchema>;
+2 -2
View File
@@ -18,7 +18,7 @@ export const registerRelayRouter = async (server: FastifyZodProvider) => {
}, },
schema: { schema: {
body: z.object({ body: z.object({
ip: z.string(), host: z.string(),
name: z.string() name: z.string()
}), }),
response: { response: {
@@ -68,7 +68,7 @@ export const registerRelayRouter = async (server: FastifyZodProvider) => {
}, },
schema: { schema: {
body: z.object({ body: z.object({
ip: z.string(), host: z.string(),
name: z.string() name: z.string()
}), }),
response: { response: {
@@ -79,7 +79,7 @@ export const KubernetesProvider = ({
); );
}, },
{ {
relayIp: gatewayV2ConnectionDetails.relayIp, relayHost: gatewayV2ConnectionDetails.relayHost,
gateway: gatewayV2ConnectionDetails.gateway, gateway: gatewayV2ConnectionDetails.gateway,
relay: gatewayV2ConnectionDetails.relay, relay: gatewayV2ConnectionDetails.relay,
protocol: inputs.reviewTokenThroughGateway ? GatewayProxyProtocol.Http : GatewayProxyProtocol.Tcp, protocol: inputs.reviewTokenThroughGateway ? GatewayProxyProtocol.Http : GatewayProxyProtocol.Tcp,
@@ -203,7 +203,7 @@ export const SqlDatabaseProvider = ({
await gatewayCallback("localhost", port); await gatewayCallback("localhost", port);
}, },
{ {
relayIp: gatewayV2ConnectionDetails.relayIp, relayHost: gatewayV2ConnectionDetails.relayHost,
gateway: gatewayV2ConnectionDetails.gateway, gateway: gatewayV2ConnectionDetails.gateway,
relay: gatewayV2ConnectionDetails.relay, relay: gatewayV2ConnectionDetails.relay,
protocol: GatewayProxyProtocol.Tcp protocol: GatewayProxyProtocol.Tcp
@@ -25,7 +25,6 @@ import { TLicenseServiceFactory } from "../license/license-service";
import { OrgPermissionGatewayActions, OrgPermissionSubjects } from "../permission/org-permission"; import { OrgPermissionGatewayActions, OrgPermissionSubjects } from "../permission/org-permission";
import { TPermissionServiceFactory } from "../permission/permission-service-types"; import { TPermissionServiceFactory } from "../permission/permission-service-types";
import { TRelayDALFactory } from "../relay/relay-dal"; import { TRelayDALFactory } from "../relay/relay-dal";
import { isInstanceRelay } from "../relay/relay-fns";
import { TRelayServiceFactory } from "../relay/relay-service"; import { TRelayServiceFactory } from "../relay/relay-service";
import { GATEWAY_ACTOR_OID, GATEWAY_ROUTING_INFO_OID } from "./gateway-v2-constants"; import { GATEWAY_ACTOR_OID, GATEWAY_ROUTING_INFO_OID } from "./gateway-v2-constants";
import { TGatewayV2DALFactory } from "./gateway-v2-dal"; import { TGatewayV2DALFactory } from "./gateway-v2-dal";
@@ -399,7 +398,7 @@ export const gatewayV2ServiceFactory = ({
}); });
return { return {
relayIp: relayCredentials.relayIp, relayHost: relayCredentials.relayHost,
gateway: { gateway: {
clientCertificate: clientCert.toString("pem"), clientCertificate: clientCert.toString("pem"),
clientPrivateKey: gatewayClientCertPrivateKey.export({ format: "pem", type: "pkcs8" }).toString(), clientPrivateKey: gatewayClientCertPrivateKey.export({ format: "pem", type: "pkcs8" }).toString(),
@@ -429,11 +428,9 @@ export const gatewayV2ServiceFactory = ({
await $validateIdentityAccessToGateway(orgId, actorId, actorAuthMethod); await $validateIdentityAccessToGateway(orgId, actorId, actorAuthMethod);
const orgCAs = await $getOrgCAs(orgId); const orgCAs = await $getOrgCAs(orgId);
let relay: TRelays; let relay: TRelays = await relayDAL.findOne({ orgId, name: relayName });
if (isInstanceRelay(relayName)) { if (!relay) {
relay = await relayDAL.findOne({ name: relayName }); relay = await relayDAL.findOne({ name: relayName, orgId: null });
} else {
relay = await relayDAL.findOne({ orgId, name: relayName });
} }
if (!relay) { if (!relay) {
@@ -515,7 +512,7 @@ export const gatewayV2ServiceFactory = ({
return { return {
gatewayId: gateway.id, gatewayId: gateway.id,
relayIp: relayCredentials.relayIp, relayHost: relayCredentials.relayHost,
pki: { pki: {
serverCertificate: gatewayServerCertificate.toString("pem"), serverCertificate: gatewayServerCertificate.toString("pem"),
serverPrivateKey: gatewayServerCertPrivateKey.export({ format: "pem", type: "pkcs8" }).toString(), serverPrivateKey: gatewayServerCertPrivateKey.export({ format: "pem", type: "pkcs8" }).toString(),
@@ -613,7 +610,7 @@ export const gatewayV2ServiceFactory = ({
}, },
{ {
protocol: GatewayProxyProtocol.Ping, protocol: GatewayProxyProtocol.Ping,
relayIp: gatewayV2ConnectionDetails.relayIp, relayHost: gatewayV2ConnectionDetails.relayHost,
gateway: gatewayV2ConnectionDetails.gateway, gateway: gatewayV2ConnectionDetails.gateway,
relay: gatewayV2ConnectionDetails.relay relay: gatewayV2ConnectionDetails.relay
} }
@@ -1,5 +0,0 @@
export const INSTANCE_RELAY_PREFIX = "infisical-";
export const isInstanceRelay = (relayName: string) => {
return relayName.startsWith(INSTANCE_RELAY_PREFIX);
};
+31 -43
View File
@@ -19,7 +19,6 @@ import { SshCertKeyAlgorithm } from "../ssh-certificate/ssh-certificate-types";
import { TInstanceRelayConfigDALFactory } from "./instance-relay-config-dal"; import { TInstanceRelayConfigDALFactory } from "./instance-relay-config-dal";
import { TOrgRelayConfigDALFactory } from "./org-relay-config-dal"; import { TOrgRelayConfigDALFactory } from "./org-relay-config-dal";
import { TRelayDALFactory } from "./relay-dal"; import { TRelayDALFactory } from "./relay-dal";
import { isInstanceRelay } from "./relay-fns";
export type TRelayServiceFactory = ReturnType<typeof relayServiceFactory>; export type TRelayServiceFactory = ReturnType<typeof relayServiceFactory>;
@@ -588,7 +587,7 @@ export const relayServiceFactory = ({
}; };
const $generateRelayServerCredentials = async ({ const $generateRelayServerCredentials = async ({
ip, host,
orgId, orgId,
relayPkiServerCaCertificate, relayPkiServerCaCertificate,
relayPkiServerCaPrivateKey, relayPkiServerCaPrivateKey,
@@ -597,7 +596,7 @@ export const relayServiceFactory = ({
relaySshClientCaPublicKey, relaySshClientCaPublicKey,
relaySshServerCaPrivateKey relaySshServerCaPrivateKey
}: { }: {
ip: string; host: string;
relayPkiServerCaCertificate: Buffer; relayPkiServerCaCertificate: Buffer;
relayPkiServerCaPrivateKey: Buffer; relayPkiServerCaPrivateKey: Buffer;
relayPkiClientCaCertificateChain: Buffer; relayPkiClientCaCertificateChain: Buffer;
@@ -640,13 +639,13 @@ export const relayServiceFactory = ({
), ),
new x509.ExtendedKeyUsageExtension([x509.ExtendedKeyUsage[CertExtendedKeyUsage.SERVER_AUTH]], true), new x509.ExtendedKeyUsageExtension([x509.ExtendedKeyUsage[CertExtendedKeyUsage.SERVER_AUTH]], true),
// san // san
new x509.SubjectAlternativeNameExtension([{ type: "ip", value: ip }], false) new x509.SubjectAlternativeNameExtension([{ type: "ip", value: host }], false)
]; ];
const relayServerSerialNumber = createSerialNumber(); const relayServerSerialNumber = createSerialNumber();
const relayServerCertificate = await x509.X509CertificateGenerator.create({ const relayServerCertificate = await x509.X509CertificateGenerator.create({
serialNumber: relayServerSerialNumber, serialNumber: relayServerSerialNumber,
subject: `CN=${ip},O=${orgId ?? "Infisical"},OU=Relay`, subject: `CN=${host},O=${orgId ?? "Infisical"},OU=Relay`,
issuer: relayServerCaCert.subject, issuer: relayServerCaCert.subject,
notBefore: relayServerCertIssuedAt, notBefore: relayServerCertIssuedAt,
notAfter: relayServerCertExpireAt, notAfter: relayServerCertExpireAt,
@@ -665,7 +664,7 @@ export const relayServiceFactory = ({
caPrivateKey: relaySshServerCaPrivateKey.toString("utf8"), caPrivateKey: relaySshServerCaPrivateKey.toString("utf8"),
clientPublicKey: relayServerSshPublicKey, clientPublicKey: relayServerSshPublicKey,
keyId: "relay-server", keyId: "relay-server",
principals: [`${ip}:2222`], principals: [`${host}:2222`],
certType: SshCertType.HOST, certType: SshCertType.HOST,
requestedTtl: "30d" requestedTtl: "30d"
}); });
@@ -772,15 +771,15 @@ export const relayServiceFactory = ({
orgId: string; orgId: string;
gatewayId: string; gatewayId: string;
}) => { }) => {
let relay: TRelays | null; let relay: TRelays | null = await relayDAL.findOne({
if (isInstanceRelay(relayName)) { orgId,
name: relayName
});
if (!relay) {
relay = await relayDAL.findOne({ relay = await relayDAL.findOne({
name: relayName name: relayName,
}); orgId: null
} else {
relay = await relayDAL.findOne({
orgId,
name: relayName
}); });
} }
@@ -794,7 +793,7 @@ export const relayServiceFactory = ({
const { publicKey: relayClientSshPublicKey, privateKey: relayClientSshPrivateKey } = const { publicKey: relayClientSshPublicKey, privateKey: relayClientSshPrivateKey } =
await createSshKeyPair(keyAlgorithm); await createSshKeyPair(keyAlgorithm);
if (isInstanceRelay(relayName)) { if (relay.orgId === null) {
const instanceCAs = await $getInstanceCAs(); const instanceCAs = await $getInstanceCAs();
const relayClientSshCert = await createSshCert({ const relayClientSshCert = await createSshCert({
caPrivateKey: instanceCAs.instanceRelaySshClientCaPrivateKey.toString("utf8"), caPrivateKey: instanceCAs.instanceRelaySshClientCaPrivateKey.toString("utf8"),
@@ -806,7 +805,7 @@ export const relayServiceFactory = ({
}); });
return { return {
relayIp: relay.ip, relayHost: relay.host,
clientSshCert: relayClientSshCert.signedPublicKey, clientSshCert: relayClientSshCert.signedPublicKey,
clientSshPrivateKey: relayClientSshPrivateKey, clientSshPrivateKey: relayClientSshPrivateKey,
serverCAPublicKey: instanceCAs.instanceRelaySshServerCaPublicKey.toString("utf8") serverCAPublicKey: instanceCAs.instanceRelaySshServerCaPublicKey.toString("utf8")
@@ -824,7 +823,7 @@ export const relayServiceFactory = ({
}); });
return { return {
relayIp: relay.ip, relayHost: relay.host,
clientSshCert: relayClientSshCert.signedPublicKey, clientSshCert: relayClientSshCert.signedPublicKey,
clientSshPrivateKey: relayClientSshPrivateKey, clientSshPrivateKey: relayClientSshPrivateKey,
serverCAPublicKey: orgCAs.relaySshServerCaPublicKey.toString("utf8") serverCAPublicKey: orgCAs.relaySshServerCaPublicKey.toString("utf8")
@@ -850,7 +849,7 @@ export const relayServiceFactory = ({
}); });
} }
if (isInstanceRelay(relay.name)) { if (relay.orgId === null) {
const instanceCAs = await $getInstanceCAs(); const instanceCAs = await $getInstanceCAs();
const relayCertificateCredentials = await $generateRelayClientCredentials({ const relayCertificateCredentials = await $generateRelayClientCredentials({
gatewayId, gatewayId,
@@ -863,7 +862,7 @@ export const relayServiceFactory = ({
return { return {
...relayCertificateCredentials, ...relayCertificateCredentials,
relayIp: relay.ip relayHost: relay.host
}; };
} }
@@ -879,17 +878,17 @@ export const relayServiceFactory = ({
return { return {
...relayCertificateCredentials, ...relayCertificateCredentials,
relayIp: relay.ip relayHost: relay.host
}; };
}; };
const registerRelay = async ({ const registerRelay = async ({
ip, host,
name, name,
identityId, identityId,
orgId orgId
}: { }: {
ip: string; host: string;
name: string; name: string;
identityId?: string; identityId?: string;
orgId?: string; orgId?: string;
@@ -898,12 +897,6 @@ export const relayServiceFactory = ({
const isOrgRelay = identityId && orgId; const isOrgRelay = identityId && orgId;
if (isOrgRelay) { if (isOrgRelay) {
if (isInstanceRelay(name)) {
throw new BadRequestError({
message: "Org relay name cannot start with 'infisical-'. This is reserved for internal use."
});
}
relay = await relayDAL.transaction(async (tx) => { relay = await relayDAL.transaction(async (tx) => {
const existingRelay = await relayDAL.findOne( const existingRelay = await relayDAL.findOne(
{ {
@@ -913,7 +906,7 @@ export const relayServiceFactory = ({
tx tx
); );
if (existingRelay && (existingRelay.ip !== ip || existingRelay.name !== name)) { if (existingRelay && (existingRelay.host !== host || existingRelay.name !== name)) {
throw new BadRequestError({ throw new BadRequestError({
message: "Org relay with this machine identity already exists." message: "Org relay with this machine identity already exists."
}); });
@@ -922,7 +915,7 @@ export const relayServiceFactory = ({
if (!existingRelay) { if (!existingRelay) {
return relayDAL.create( return relayDAL.create(
{ {
ip, host,
name, name,
identityId, identityId,
orgId orgId
@@ -934,30 +927,25 @@ export const relayServiceFactory = ({
return existingRelay; return existingRelay;
}); });
} else { } else {
if (!isInstanceRelay(name)) {
throw new BadRequestError({
message: "Instance relay name must start with 'infisical-'."
});
}
relay = await relayDAL.transaction(async (tx) => { relay = await relayDAL.transaction(async (tx) => {
const existingRelay = await relayDAL.findOne( const existingRelay = await relayDAL.findOne(
{ {
name name,
orgId: null
}, },
tx tx
); );
if (existingRelay && existingRelay.ip !== ip) { if (existingRelay && existingRelay.host !== host) {
throw new BadRequestError({ throw new BadRequestError({
message: "Instance relay with this name already exists with a different IP address" message: "Instance relay with this name already exists with a different host"
}); });
} }
if (!existingRelay) { if (!existingRelay) {
return relayDAL.create( return relayDAL.create(
{ {
ip, host,
name name
}, },
tx tx
@@ -968,10 +956,10 @@ export const relayServiceFactory = ({
}); });
} }
if (isInstanceRelay(name)) { if (relay.orgId === null) {
const instanceCAs = await $getInstanceCAs(); const instanceCAs = await $getInstanceCAs();
return $generateRelayServerCredentials({ return $generateRelayServerCredentials({
ip, host,
relayPkiServerCaCertificate: instanceCAs.instanceRelayPkiServerCaCertificate, relayPkiServerCaCertificate: instanceCAs.instanceRelayPkiServerCaCertificate,
relayPkiServerCaPrivateKey: instanceCAs.instanceRelayPkiServerCaPrivateKey, relayPkiServerCaPrivateKey: instanceCAs.instanceRelayPkiServerCaPrivateKey,
relayPkiClientCaCertificate: instanceCAs.instanceRelayPkiClientCaCertificate, relayPkiClientCaCertificate: instanceCAs.instanceRelayPkiClientCaCertificate,
@@ -984,7 +972,7 @@ export const relayServiceFactory = ({
if (relay.orgId) { if (relay.orgId) {
const orgCAs = await $getOrgCAs(relay.orgId); const orgCAs = await $getOrgCAs(relay.orgId);
return $generateRelayServerCredentials({ return $generateRelayServerCredentials({
ip, host,
orgId: relay.orgId, orgId: relay.orgId,
relayPkiServerCaCertificate: orgCAs.relayPkiServerCaCertificate, relayPkiServerCaCertificate: orgCAs.relayPkiServerCaCertificate,
relayPkiServerCaPrivateKey: orgCAs.relayPkiServerCaPrivateKey, relayPkiServerCaPrivateKey: orgCAs.relayPkiServerCaPrivateKey,
+11 -10
View File
@@ -19,23 +19,24 @@ interface IGatewayRelayServer {
} }
const createRelayConnection = async ({ const createRelayConnection = async ({
relayIp, relayHost,
clientCertificate, clientCertificate,
clientPrivateKey, clientPrivateKey,
serverCertificateChain serverCertificateChain
}: { }: {
relayIp: string; relayHost: string;
clientCertificate: string; clientCertificate: string;
clientPrivateKey: string; clientPrivateKey: string;
serverCertificateChain: string; serverCertificateChain: string;
}): Promise<net.Socket> => { }): Promise<net.Socket> => {
const [targetHost] = await verifyHostInputValidity(relayIp); const [targetHost] = await verifyHostInputValidity(relayHost);
const [, portStr] = relayIp.split(":"); const [, portStr] = relayHost.split(":");
const port = parseInt(portStr, 10) || 8443; const port = parseInt(portStr, 10) || 8443;
const serverCAs = splitPemChain(serverCertificateChain); const serverCAs = splitPemChain(serverCertificateChain);
const tlsOptions: tls.ConnectionOptions = { const tlsOptions: tls.ConnectionOptions = {
host: targetHost, host: targetHost,
servername: relayHost,
port, port,
cert: clientCertificate, cert: clientCertificate,
key: clientPrivateKey, key: clientPrivateKey,
@@ -121,13 +122,13 @@ const createGatewayConnection = async (
const setupRelayServer = async ({ const setupRelayServer = async ({
protocol, protocol,
relayIp, relayHost,
gateway, gateway,
relay, relay,
httpsAgent httpsAgent
}: { }: {
protocol: GatewayProxyProtocol; protocol: GatewayProxyProtocol;
relayIp: string; relayHost: string;
gateway: { clientCertificate: string; clientPrivateKey: string; serverCertificateChain: string }; gateway: { clientCertificate: string; clientPrivateKey: string; serverCertificateChain: string };
relay: { clientCertificate: string; clientPrivateKey: string; serverCertificateChain: string }; relay: { clientCertificate: string; clientPrivateKey: string; serverCertificateChain: string };
httpsAgent?: https.Agent; httpsAgent?: https.Agent;
@@ -145,7 +146,7 @@ const setupRelayServer = async ({
// Stage 1: Connect to relay with TLS // Stage 1: Connect to relay with TLS
const relayConn = await createRelayConnection({ const relayConn = await createRelayConnection({
relayIp, relayHost,
clientCertificate: relay.clientCertificate, clientCertificate: relay.clientCertificate,
clientPrivateKey: relay.clientPrivateKey, clientPrivateKey: relay.clientPrivateKey,
serverCertificateChain: relay.serverCertificateChain serverCertificateChain: relay.serverCertificateChain
@@ -244,17 +245,17 @@ export const withGatewayV2Proxy = async <T>(
callback: (port: number) => Promise<T>, callback: (port: number) => Promise<T>,
options: { options: {
protocol: GatewayProxyProtocol; protocol: GatewayProxyProtocol;
relayIp: string; relayHost: string;
gateway: { clientCertificate: string; clientPrivateKey: string; serverCertificateChain: string }; gateway: { clientCertificate: string; clientPrivateKey: string; serverCertificateChain: string };
relay: { clientCertificate: string; clientPrivateKey: string; serverCertificateChain: string }; relay: { clientCertificate: string; clientPrivateKey: string; serverCertificateChain: string };
httpsAgent?: https.Agent; httpsAgent?: https.Agent;
} }
): Promise<T> => { ): Promise<T> => {
const { protocol, relayIp, gateway, relay, httpsAgent } = options; const { protocol, relayHost, gateway, relay, httpsAgent } = options;
const { port, cleanup, getRelayError } = await setupRelayServer({ const { port, cleanup, getRelayError } = await setupRelayServer({
protocol, protocol,
relayIp, relayHost,
gateway, gateway,
relay, relay,
httpsAgent httpsAgent
@@ -105,7 +105,7 @@ export const requestWithGitHubGateway = async <T>(
}, },
{ {
protocol: GatewayProxyProtocol.Tcp, protocol: GatewayProxyProtocol.Tcp,
relayIp: gatewayConnectionDetails.relayIp, relayHost: gatewayConnectionDetails.relayHost,
gateway: gatewayConnectionDetails.gateway, gateway: gatewayConnectionDetails.gateway,
relay: gatewayConnectionDetails.relay relay: gatewayConnectionDetails.relay
} }
@@ -142,7 +142,7 @@ export const executeWithPotentialGateway = async <T>(
}, },
{ {
protocol: GatewayProxyProtocol.Tcp, protocol: GatewayProxyProtocol.Tcp,
relayIp: platformConnectionDetails.relayIp, relayHost: platformConnectionDetails.relayHost,
gateway: platformConnectionDetails.gateway, gateway: platformConnectionDetails.gateway,
relay: platformConnectionDetails.relay relay: platformConnectionDetails.relay
} }
@@ -114,7 +114,7 @@ export const identityKubernetesAuthServiceFactory = ({
}, },
{ {
protocol: inputs.reviewTokenThroughGateway ? GatewayProxyProtocol.Http : GatewayProxyProtocol.Tcp, protocol: inputs.reviewTokenThroughGateway ? GatewayProxyProtocol.Http : GatewayProxyProtocol.Tcp,
relayIp: gatewayV2ConnectionDetails.relayIp, relayHost: gatewayV2ConnectionDetails.relayHost,
gateway: gatewayV2ConnectionDetails.gateway, gateway: gatewayV2ConnectionDetails.gateway,
relay: gatewayV2ConnectionDetails.relay, relay: gatewayV2ConnectionDetails.relay,
httpsAgent httpsAgent
+23 -20
View File
@@ -6,7 +6,7 @@ description: "Relay-related commands for Infisical including proxy components"
<Tabs> <Tabs>
<Tab title="Start relay"> <Tab title="Start relay">
```bash ```bash
infisical relay start --type=<type> --ip=<ip> --name=<name> --auth-method=<auth-method> infisical relay start --type=<type> --host=<host> --name=<name> --auth-method=<auth-method>
``` ```
</Tab> </Tab>
</Tabs> </Tabs>
@@ -25,7 +25,7 @@ The relay system uses SSH reverse tunnels over TCP, eliminating firewall complex
Run the Infisical relay component. The relay handles network traffic routing and can operate in different modes. Run the Infisical relay component. The relay handles network traffic routing and can operate in different modes.
```bash ```bash
infisical relay start --type=<type> --ip=<ip> --name=<name> --auth-method=<auth-method> infisical relay start --type=<type> --host=<host> --name=<name> --auth-method=<auth-method>
``` ```
### Flags ### Flags
@@ -38,20 +38,23 @@ infisical relay start --type=<type> --ip=<ip> --name=<name> --auth-method=<auth-
```bash ```bash
# Organization relay (customer-deployed) # Organization relay (customer-deployed)
infisical relay start --type=org --ip=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 --ip=10.0.1.50 --name=shared-relay INFISICAL_PROXY_AUTH_SECRET=<secret> infisical relay start --type=instance --host=10.0.1.50 --name=shared-relay
``` ```
</Accordion> </Accordion>
<Accordion title="--ip"> <Accordion title="--host">
The public IP address of the instance where the relay is deployed. This must be a static public IP that gateways can reach. The host (IP address or hostname) of the instance where the relay is deployed. This must be a static public IP or resolvable hostname that gateways can reach.
```bash ```bash
# Example # Example with IP address
infisical relay start --ip=203.0.113.100 --type=org --name=my-relay infisical relay start --host=203.0.113.100 --type=org --name=my-relay
# Example with hostname
infisical relay start --host=relay.example.com --type=org --name=my-relay
``` ```
</Accordion> </Accordion>
@@ -61,7 +64,7 @@ infisical relay start --type=<type> --ip=<ip> --name=<name> --auth-method=<auth-
```bash ```bash
# Example # Example
infisical relay start --name=my-relay --type=org --ip=192.168.1.100 infisical relay start --name=my-relay --type=org --host=192.168.1.100
``` ```
</Accordion> </Accordion>
@@ -76,10 +79,10 @@ Shared relay servers that serve all organizations on your Infisical instance. Fo
```bash ```bash
# Organization relay with Universal Auth (customer-deployed) # Organization relay with Universal Auth (customer-deployed)
infisical relay start --type=org --ip=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 --ip=10.0.1.50 --name=shared-relay INFISICAL_PROXY_AUTH_SECRET=<secret> infisical relay start --type=instance --host=10.0.1.50 --name=shared-relay
``` ```
### Authentication Methods ### Authentication Methods
@@ -105,7 +108,7 @@ The Infisical CLI supports multiple authentication methods for organization rela
</ParamField> </ParamField>
```bash ```bash
infisical relay start --auth-method=universal-auth --client-id=<client-id> --client-secret=<client-secret> --type=org --ip=<ip> --name=<name> infisical relay start --auth-method=universal-auth --client-id=<client-id> --client-secret=<client-secret> --type=org --host=<host> --name=<name>
``` ```
</Accordion> </Accordion>
@@ -129,7 +132,7 @@ The Infisical CLI supports multiple authentication methods for organization rela
```bash ```bash
infisical relay start --auth-method=kubernetes --machine-identity-id=<machine-identity-id> --type=org --ip=<ip> --name=<name> infisical relay start --auth-method=kubernetes --machine-identity-id=<machine-identity-id> --type=org --host=<host> --name=<name>
``` ```
</Accordion> </Accordion>
@@ -150,7 +153,7 @@ The Infisical CLI supports multiple authentication methods for organization rela
```bash ```bash
infisical relay start --auth-method=azure --machine-identity-id=<machine-identity-id> --type=org --ip=<ip> --name=<name> infisical relay start --auth-method=azure --machine-identity-id=<machine-identity-id> --type=org --host=<host> --name=<name>
``` ```
</Accordion> </Accordion>
@@ -171,7 +174,7 @@ The Infisical CLI supports multiple authentication methods for organization rela
```bash ```bash
infisical relay start --auth-method=gcp-id-token --machine-identity-id=<machine-identity-id> --type=org --ip=<ip> --name=<name> infisical relay start --auth-method=gcp-id-token --machine-identity-id=<machine-identity-id> --type=org --host=<host> --name=<name>
``` ```
</Accordion> </Accordion>
@@ -193,7 +196,7 @@ The Infisical CLI supports multiple authentication methods for organization rela
</ParamField> </ParamField>
```bash ```bash
infisical relay start --auth-method=gcp-iam --machine-identity-id=<machine-identity-id> --service-account-key-file-path=<service-account-key-file-path> --type=org --ip=<ip> --name=<name> infisical relay start --auth-method=gcp-iam --machine-identity-id=<machine-identity-id> --service-account-key-file-path=<service-account-key-file-path> --type=org --host=<host> --name=<name>
``` ```
</Accordion> </Accordion>
@@ -212,7 +215,7 @@ The Infisical CLI supports multiple authentication methods for organization rela
</ParamField> </ParamField>
```bash ```bash
infisical relay start --auth-method=aws-iam --machine-identity-id=<machine-identity-id> --type=org --ip=<ip> --name=<name> infisical relay start --auth-method=aws-iam --machine-identity-id=<machine-identity-id> --type=org --host=<host> --name=<name>
``` ```
</Accordion> </Accordion>
@@ -234,7 +237,7 @@ The Infisical CLI supports multiple authentication methods for organization rela
</ParamField> </ParamField>
```bash ```bash
infisical relay start --auth-method=oidc-auth --machine-identity-id=<machine-identity-id> --jwt=<oidc-jwt> --type=org --ip=<ip> --name=<name> infisical relay start --auth-method=oidc-auth --machine-identity-id=<machine-identity-id> --jwt=<oidc-jwt> --type=org --host=<host> --name=<name>
``` ```
</Accordion> </Accordion>
@@ -258,7 +261,7 @@ The Infisical CLI supports multiple authentication methods for organization rela
```bash ```bash
infisical relay start --auth-method=jwt-auth --jwt=<jwt> --machine-identity-id=<machine-identity-id> --type=org --ip=<ip> --name=<name> infisical relay start --auth-method=jwt-auth --jwt=<jwt> --machine-identity-id=<machine-identity-id> --type=org --host=<host> --name=<name>
``` ```
</Accordion> </Accordion>
@@ -274,7 +277,7 @@ The Infisical CLI supports multiple authentication methods for organization rela
</ParamField> </ParamField>
```bash ```bash
infisical relay start --token=<token> --type=org --ip=<ip> --name=<name> infisical relay start --token=<token> --type=org --host=<host> --name=<name>
``` ```
</Accordion> </Accordion>
@@ -30,7 +30,7 @@ The gateway requires the following outbound connectivity:
**For Instance Relays (Infisical Cloud):** Your firewall must allow outbound connectivity to Infisical-managed relay servers. **For Instance Relays (Infisical Cloud):** Your firewall must allow outbound connectivity to Infisical-managed relay servers.
**For Organization Relays:** Your firewall must allow outbound connectivity to your own relay server IP addresses. **For Organization Relays:** Your firewall must allow outbound connectivity to your own relay server IP addresses or hostnames.
**For Self-hosted Instance Relays:** Your firewall must allow outbound connectivity to relay servers configured by your instance administrator. **For Self-hosted Instance Relays:** Your firewall must allow outbound connectivity to relay servers configured by your instance administrator.
@@ -42,15 +42,16 @@ The gateway requires the following outbound connectivity:
connections to the desired relay server IP on port 2222. connections to the desired relay server IP on port 2222.
</Tab> </Tab>
<Tab title="Organization Relays"> <Tab title="Organization Relays">
You control the relay server IP addresses when deploying your own You control the relay server IP addresses or hostnames when deploying your
organization relays. **Firewall requirements:** Allow outbound TCP own organization relays. **Firewall requirements:** Allow outbound TCP
connections to your relay server IP on port 2222. For example, if your relay connections to your relay server IP or hostname on port 2222. For example,
is at `203.0.113.100`, allow TCP to `203.0.113.100:2222`. if your relay is at `203.0.113.100` or `relay.example.com`, allow TCP to
`203.0.113.100:2222` or `relay.example.com:2222`.
</Tab> </Tab>
<Tab title="Self-hosted Instance Relays"> <Tab title="Self-hosted Instance Relays">
Contact your instance administrator for the relay server IP addresses Contact your instance administrator for the relay server IP addresses or
configured for your deployment. **Firewall requirements:** Allow outbound hostnames configured for your deployment. **Firewall requirements:** Allow
TCP connections to instance relay servers on port 2222. outbound TCP connections to instance relay servers on port 2222.
</Tab> </Tab>
</Tabs> </Tabs>
@@ -81,7 +82,7 @@ SSH connections over TCP are stateful and handled seamlessly by all modern firew
Since SSH uses TCP, you only need simple outbound rules: Since SSH uses TCP, you only need simple outbound rules:
1. **Allow outbound TCP** to relay servers on port 2222 1. **Allow outbound TCP** to relay servers (IP addresses or hostnames) on port 2222
2. **Allow outbound HTTPS** to Infisical API endpoints on port 443 2. **Allow outbound HTTPS** to Infisical API endpoints on port 443
3. **No inbound rules required** - all connections are outbound only 3. **No inbound rules required** - all connections are outbound only
@@ -91,7 +92,7 @@ Since SSH uses TCP, you only need simple outbound rules:
For corporate environments with strict egress filtering: For corporate environments with strict egress filtering:
1. **Allow outbound TCP** to relay servers on port 2222 1. **Allow outbound TCP** to relay servers (IP addresses or hostnames) on port 2222
2. **Allow outbound HTTPS** to the Infisical API server on port 443 2. **Allow outbound HTTPS** to the Infisical API server on port 443
3. **No inbound rules required** - all connections are outbound only 3. **No inbound rules required** - all connections are outbound only
4. **Standard TCP rules** - simple and straightforward configuration 4. **Standard TCP rules** - simple and straightforward configuration
@@ -100,7 +101,7 @@ For corporate environments with strict egress filtering:
Configure security groups to allow: Configure security groups to allow:
- **Outbound TCP** to relay servers on port 2222 - **Outbound TCP** to relay servers (IP addresses or hostnames) on port 2222
- **Outbound HTTPS** to app.infisical.com/eu.infisical.com on port 443 - **Outbound HTTPS** to app.infisical.com/eu.infisical.com on port 443
- **No inbound rules required** - SSH reverse tunnels are outbound only - **No inbound rules required** - SSH reverse tunnels are outbound only
@@ -146,7 +147,7 @@ This design maintains security by avoiding the need for inbound firewall rules t
<Accordion title="What if my firewall blocks SSH connections?"> <Accordion title="What if my firewall blocks SSH connections?">
If your firewall has strict outbound restrictions: If your firewall has strict outbound restrictions:
1. **Work with your network team** to allow outbound TCP connections on port 2222 to relay servers 1. **Work with your network team** to allow outbound TCP connections on port 2222 to relay servers (IP addresses or hostnames)
2. **Allow standard SSH traffic** - most enterprises already have SSH policies in place 2. **Allow standard SSH traffic** - most enterprises already have SSH policies in place
3. **Consider network policy exceptions** for the gateway host if needed 3. **Consider network policy exceptions** for the gateway host if needed
4. **Monitor firewall logs** to identify which specific rules are blocking traffic 4. **Monitor firewall logs** to identify which specific rules are blocking traffic