Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
cc34b92
feat: pki and ssh setup for instance proxy
sheensantoscapadngan Aug 25, 2025
ae62c59
feat: add gateway registration and org-proxy initialization
sheensantoscapadngan Aug 26, 2025
2fb1346
misc: add schema for gateway
sheensantoscapadngan Aug 28, 2025
81dfcb5
feat: gateway registration + start of gateway v2 integration
sheensantoscapadngan Aug 29, 2025
879361f
feat: half-way done through integrating with platform
sheensantoscapadngan Sep 1, 2025
d5dcaf0
feat: added heartbeat and fixed up gateway page
sheensantoscapadngan Sep 2, 2025
9a9cdf1
feat: integrated with github app connection to gateway and some adjus…
sheensantoscapadngan Sep 3, 2025
e30cb9d
Merge remote-tracking branch 'origin/main' into feat/gateway-v2
sheensantoscapadngan Sep 3, 2025
ec39f84
misc: addressed greptile comments 1
sheensantoscapadngan Sep 3, 2025
e00df2c
mics: added missing github app connection usage
sheensantoscapadngan Sep 3, 2025
54cd93a
misc: added proper error message handling
sheensantoscapadngan Sep 3, 2025
a22903b
misc: improved error being thrown
sheensantoscapadngan Sep 3, 2025
d994cb0
misc: updated helm chart for gateway v2
sheensantoscapadngan Sep 3, 2025
0a9f51f
doc: cli docs for gateway v2
sheensantoscapadngan Sep 3, 2025
4d22030
doc: added platform dcs
sheensantoscapadngan Sep 3, 2025
4f7b0ea
misc: added proper handling for gateway name conflicts
sheensantoscapadngan Sep 4, 2025
09d179f
misc: addressed comments
sheensantoscapadngan Sep 5, 2025
c9136a2
misc: updated proxy terminology to relay
sheensantoscapadngan Sep 8, 2025
43d6c13
Merge remote-tracking branch 'origin/main' into feat/gateway-v2
sheensantoscapadngan Sep 8, 2025
49742b2
misc: doc updates
sheensantoscapadngan Sep 8, 2025
b7dcc10
Merge remote-tracking branch 'origin/main' into feat/gateway-v2
sheensantoscapadngan Sep 8, 2025
1839845
misc: addressed comments
sheensantoscapadngan Sep 8, 2025
27d2512
misc: corrected gateway registration endpoint
sheensantoscapadngan Sep 8, 2025
0ed6601
misc: added version indicator
sheensantoscapadngan Sep 8, 2025
c297961
misc: updated remaining proxy remnants
sheensantoscapadngan Sep 8, 2025
f86f3ce
misc: moved protocol indicator to alpn header
sheensantoscapadngan Sep 8, 2025
1dcdb90
misc: add fix for v2 to app connection
sheensantoscapadngan Sep 9, 2025
71ff01d
misc: addressed comments
sheensantoscapadngan Sep 10, 2025
26de424
Merge remote-tracking branch 'origin/main' into feat/gateway-v2
sheensantoscapadngan Sep 10, 2025
cb3ba75
misc: shortened cert expiry
sheensantoscapadngan Sep 10, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions backend/src/@types/fastify.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { TEventBusService } from "@app/ee/services/event/event-bus-service";
import { TServerSentEventsService } from "@app/ee/services/event/event-sse-service";
Comment thread
sheensantoscapadngan marked this conversation as resolved.
import { TExternalKmsServiceFactory } from "@app/ee/services/external-kms/external-kms-service";
import { TGatewayServiceFactory } from "@app/ee/services/gateway/gateway-service";
Comment thread
sheensantoscapadngan marked this conversation as resolved.
import { TGatewayV2ServiceFactory } from "@app/ee/services/gateway-v2/gateway-v2-service";
import { TGithubOrgSyncServiceFactory } from "@app/ee/services/github-org-sync/github-org-sync-service";
Comment thread
sheensantoscapadngan marked this conversation as resolved.
import { TGroupServiceFactory } from "@app/ee/services/group/group-service";
import { TIdentityAuthTemplateServiceFactory } from "@app/ee/services/identity-auth-template";
Comment thread
akhilmhdh marked this conversation as resolved.
Expand All @@ -32,6 +33,7 @@ import { TPitServiceFactory } from "@app/ee/services/pit/pit-service";
import { TProjectTemplateServiceFactory } from "@app/ee/services/project-template/project-template-types";
Comment thread
sheensantoscapadngan marked this conversation as resolved.
import { TProjectUserAdditionalPrivilegeServiceFactory } from "@app/ee/services/project-user-additional-privilege/project-user-additional-privilege-types";
import { RateLimitConfiguration, TRateLimitServiceFactory } from "@app/ee/services/rate-limit/rate-limit-types";
import { TRelayServiceFactory } from "@app/ee/services/relay/relay-service";
import { TSamlConfigServiceFactory } from "@app/ee/services/saml-config/saml-config-types";
import { TScimServiceFactory } from "@app/ee/services/scim/scim-types";
import { TSecretApprovalPolicyServiceFactory } from "@app/ee/services/secret-approval-policy/secret-approval-policy-service";
Expand Down Expand Up @@ -296,6 +298,8 @@ declare module "fastify" {
secretRotationV2: TSecretRotationV2ServiceFactory;
microsoftTeams: TMicrosoftTeamsServiceFactory;
assumePrivileges: TAssumePrivilegeServiceFactory;
relay: TRelayServiceFactory;
gatewayV2: TGatewayV2ServiceFactory;
githubOrgSync: TGithubOrgSyncServiceFactory;
folderCommit: TFolderCommitServiceFactory;
pit: TPitServiceFactory;
Expand Down
32 changes: 32 additions & 0 deletions backend/src/@types/knex.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,9 @@ import {
TGateways,
TGatewaysInsert,
TGatewaysUpdate,
TGatewaysV2,
TGatewaysV2Insert,
TGatewaysV2Update,
TGitAppInstallSessions,
TGitAppInstallSessionsInsert,
TGitAppInstallSessionsUpdate,
Expand Down Expand Up @@ -179,6 +182,9 @@ import {
TIncidentContacts,
TIncidentContactsInsert,
TIncidentContactsUpdate,
TInstanceRelayConfig,
TInstanceRelayConfigInsert,
TInstanceRelayConfigUpdate,
TIntegrationAuths,
TIntegrationAuthsInsert,
TIntegrationAuthsUpdate,
Expand Down Expand Up @@ -233,9 +239,15 @@ import {
TOrgGatewayConfig,
TOrgGatewayConfigInsert,
TOrgGatewayConfigUpdate,
TOrgGatewayConfigV2,
TOrgGatewayConfigV2Insert,
TOrgGatewayConfigV2Update,
TOrgMemberships,
TOrgMembershipsInsert,
TOrgMembershipsUpdate,
TOrgRelayConfig,
TOrgRelayConfigInsert,
TOrgRelayConfigUpdate,
TOrgRoles,
TOrgRolesInsert,
TOrgRolesUpdate,
Expand Down Expand Up @@ -293,6 +305,9 @@ import {
TRateLimit,
TRateLimitInsert,
TRateLimitUpdate,
TRelays,
TRelaysInsert,
TRelaysUpdate,
TResourceMetadata,
TResourceMetadataInsert,
TResourceMetadataUpdate,
Expand Down Expand Up @@ -1241,6 +1256,17 @@ declare module "knex/types/tables" {
TSecretScanningResourcesInsert,
TSecretScanningResourcesUpdate
>;
[TableName.InstanceRelayConfig]: KnexOriginal.CompositeTableType<
TInstanceRelayConfig,
TInstanceRelayConfigInsert,
TInstanceRelayConfigUpdate
>;
[TableName.OrgRelayConfig]: KnexOriginal.CompositeTableType<
TOrgRelayConfig,
TOrgRelayConfigInsert,
TOrgRelayConfigUpdate
>;
[TableName.Relay]: KnexOriginal.CompositeTableType<TRelays, TRelaysInsert, TRelaysUpdate>;
[TableName.SecretScanningScan]: KnexOriginal.CompositeTableType<
TSecretScanningScans,
TSecretScanningScansInsert,
Expand All @@ -1262,6 +1288,12 @@ declare module "knex/types/tables" {
TRemindersRecipientsInsert,
TRemindersRecipientsUpdate
>;
[TableName.OrgGatewayConfigV2]: KnexOriginal.CompositeTableType<
TOrgGatewayConfigV2,
TOrgGatewayConfigV2Insert,
TOrgGatewayConfigV2Update
>;
[TableName.GatewayV2]: KnexOriginal.CompositeTableType<TGatewaysV2, TGatewaysV2Insert, TGatewaysV2Update>;
[TableName.UserNotifications]: KnexOriginal.CompositeTableType<
TUserNotifications,
TUserNotificationsInsert,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
import { Knex } from "knex";

import { TableName } from "../schemas";
import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils";

export async function up(knex: Knex): Promise<void> {
if (!(await knex.schema.hasTable(TableName.InstanceRelayConfig))) {
await knex.schema.createTable(TableName.InstanceRelayConfig, (t) => {
t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid());
t.timestamps(true, true, true);

// Root CA for relay PKI
t.binary("encryptedRootRelayPkiCaPrivateKey").notNullable();
t.binary("encryptedRootRelayPkiCaCertificate").notNullable();

// Instance CA for relay PKI
t.binary("encryptedInstanceRelayPkiCaPrivateKey").notNullable();
t.binary("encryptedInstanceRelayPkiCaCertificate").notNullable();
t.binary("encryptedInstanceRelayPkiCaCertificateChain").notNullable();

// Instance client/server intermediates for relay PKI
t.binary("encryptedInstanceRelayPkiClientCaPrivateKey").notNullable();
t.binary("encryptedInstanceRelayPkiClientCaCertificate").notNullable();
t.binary("encryptedInstanceRelayPkiClientCaCertificateChain").notNullable();
t.binary("encryptedInstanceRelayPkiServerCaPrivateKey").notNullable();
t.binary("encryptedInstanceRelayPkiServerCaCertificate").notNullable();
t.binary("encryptedInstanceRelayPkiServerCaCertificateChain").notNullable();

// Org Parent CAs for relay
t.binary("encryptedOrgRelayPkiCaPrivateKey").notNullable();
t.binary("encryptedOrgRelayPkiCaCertificate").notNullable();
t.binary("encryptedOrgRelayPkiCaCertificateChain").notNullable();

// Instance SSH CAs for relay
t.binary("encryptedInstanceRelaySshClientCaPrivateKey").notNullable();
t.binary("encryptedInstanceRelaySshClientCaPublicKey").notNullable();
t.binary("encryptedInstanceRelaySshServerCaPrivateKey").notNullable();
t.binary("encryptedInstanceRelaySshServerCaPublicKey").notNullable();
});

await createOnUpdateTrigger(knex, TableName.InstanceRelayConfig);
}

// Org-level relay configuration (one-to-one with organization)
if (!(await knex.schema.hasTable(TableName.OrgRelayConfig))) {
await knex.schema.createTable(TableName.OrgRelayConfig, (t) => {
t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid());
t.timestamps(true, true, true);

t.uuid("orgId").notNullable().unique();
t.foreign("orgId").references("id").inTable(TableName.Organization).onDelete("CASCADE");

// Org-scoped relay PKI (client + server)
t.binary("encryptedRelayPkiClientCaPrivateKey").notNullable();
t.binary("encryptedRelayPkiClientCaCertificate").notNullable();
t.binary("encryptedRelayPkiClientCaCertificateChain").notNullable();
t.binary("encryptedRelayPkiServerCaPrivateKey").notNullable();
t.binary("encryptedRelayPkiServerCaCertificate").notNullable();
t.binary("encryptedRelayPkiServerCaCertificateChain").notNullable();

// Org-scoped relay SSH (client + server)
t.binary("encryptedRelaySshClientCaPrivateKey").notNullable();
t.binary("encryptedRelaySshClientCaPublicKey").notNullable();
t.binary("encryptedRelaySshServerCaPrivateKey").notNullable();
t.binary("encryptedRelaySshServerCaPublicKey").notNullable();
});

await createOnUpdateTrigger(knex, TableName.OrgRelayConfig);
}

if (!(await knex.schema.hasTable(TableName.OrgGatewayConfigV2))) {
await knex.schema.createTable(TableName.OrgGatewayConfigV2, (t) => {
t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid());
t.uuid("orgId").notNullable().unique();
t.foreign("orgId").references("id").inTable(TableName.Organization).onDelete("CASCADE");
t.timestamps(true, true, true);
t.binary("encryptedRootGatewayCaPrivateKey").notNullable();
t.binary("encryptedRootGatewayCaCertificate").notNullable();
t.binary("encryptedGatewayServerCaPrivateKey").notNullable();
t.binary("encryptedGatewayServerCaCertificate").notNullable();
t.binary("encryptedGatewayServerCaCertificateChain").notNullable();
t.binary("encryptedGatewayClientCaPrivateKey").notNullable();
t.binary("encryptedGatewayClientCaCertificate").notNullable();
t.binary("encryptedGatewayClientCaCertificateChain").notNullable();
});

await createOnUpdateTrigger(knex, TableName.OrgGatewayConfigV2);
}

if (!(await knex.schema.hasTable(TableName.Relay))) {
await knex.schema.createTable(TableName.Relay, (t) => {
t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid());
t.timestamps(true, true, true);

t.uuid("orgId");
t.foreign("orgId").references("id").inTable(TableName.Organization).onDelete("CASCADE");

t.uuid("identityId");
t.foreign("identityId").references("id").inTable(TableName.Identity).onDelete("CASCADE");
Comment thread
sheensantoscapadngan marked this conversation as resolved.

t.string("name").notNullable();
t.string("host").notNullable();

t.unique(["orgId", "name"]);
});

await createOnUpdateTrigger(knex, TableName.Relay);
}

if (!(await knex.schema.hasTable(TableName.GatewayV2))) {
await knex.schema.createTable(TableName.GatewayV2, (t) => {
t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid());
t.timestamps(true, true, true);

t.uuid("orgId").notNullable();
t.foreign("orgId").references("id").inTable(TableName.Organization).onDelete("CASCADE");

t.uuid("identityId").notNullable().unique();
t.foreign("identityId").references("id").inTable(TableName.Identity).onDelete("CASCADE");

t.uuid("relayId");
t.foreign("relayId").references("id").inTable(TableName.Relay).onDelete("SET NULL");

t.string("name").notNullable();

t.unique(["orgId", "name"]);

t.dateTime("heartbeat");
});

await createOnUpdateTrigger(knex, TableName.GatewayV2);
}
}

export async function down(knex: Knex): Promise<void> {
await dropOnUpdateTrigger(knex, TableName.OrgRelayConfig);
await knex.schema.dropTableIfExists(TableName.OrgRelayConfig);

await dropOnUpdateTrigger(knex, TableName.InstanceRelayConfig);
await knex.schema.dropTableIfExists(TableName.InstanceRelayConfig);

await dropOnUpdateTrigger(knex, TableName.OrgGatewayConfigV2);
await knex.schema.dropTableIfExists(TableName.OrgGatewayConfigV2);

await dropOnUpdateTrigger(knex, TableName.GatewayV2);
await knex.schema.dropTableIfExists(TableName.GatewayV2);

await dropOnUpdateTrigger(knex, TableName.Relay);
await knex.schema.dropTableIfExists(TableName.Relay);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { Knex } from "knex";

import { TableName } from "../schemas";

export async function up(knex: Knex): Promise<void> {
if (!(await knex.schema.hasColumn(TableName.DynamicSecret, "gatewayV2Id"))) {
await knex.schema.alterTable(TableName.DynamicSecret, (table) => {
table.uuid("gatewayV2Id");
table.foreign("gatewayV2Id").references("id").inTable(TableName.GatewayV2).onDelete("SET NULL");
});
}

if (!(await knex.schema.hasColumn(TableName.IdentityKubernetesAuth, "gatewayV2Id"))) {
await knex.schema.alterTable(TableName.IdentityKubernetesAuth, (table) => {
table.uuid("gatewayV2Id");
table.foreign("gatewayV2Id").references("id").inTable(TableName.GatewayV2).onDelete("SET NULL");
});
}
}

export async function down(knex: Knex): Promise<void> {
if (await knex.schema.hasColumn(TableName.DynamicSecret, "gatewayV2Id")) {
await knex.schema.alterTable(TableName.DynamicSecret, (table) => {
table.dropColumn("gatewayV2Id");
});
Comment thread
sheensantoscapadngan marked this conversation as resolved.
}

if (await knex.schema.hasColumn(TableName.IdentityKubernetesAuth, "gatewayV2Id")) {
await knex.schema.alterTable(TableName.IdentityKubernetesAuth, (table) => {
table.dropColumn("gatewayV2Id");
});
Comment thread
sheensantoscapadngan marked this conversation as resolved.
}
}
3 changes: 2 additions & 1 deletion backend/src/db/schemas/dynamic-secrets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ export const DynamicSecretsSchema = z.object({
encryptedInput: zodBuffer,
projectGatewayId: z.string().uuid().nullable().optional(),
gatewayId: z.string().uuid().nullable().optional(),
usernameTemplate: z.string().nullable().optional()
usernameTemplate: z.string().nullable().optional(),
gatewayV2Id: z.string().uuid().nullable().optional()
});

export type TDynamicSecrets = z.infer<typeof DynamicSecretsSchema>;
Expand Down
23 changes: 23 additions & 0 deletions backend/src/db/schemas/gateways-v2.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Code generated by automation script, DO NOT EDIT.
// Automated by pulling database and generating zod schema
// To update. Just run npm run generate:schema
// Written by akhilmhdh.

import { z } from "zod";

import { TImmutableDBKeys } from "./models";

export const GatewaysV2Schema = z.object({
id: z.string().uuid(),
createdAt: z.date(),
updatedAt: z.date(),
orgId: z.string().uuid(),
identityId: z.string().uuid(),
relayId: z.string().uuid().nullable().optional(),
name: z.string(),
Comment thread
sheensantoscapadngan marked this conversation as resolved.
heartbeat: z.date().nullable().optional()
});

export type TGatewaysV2 = z.infer<typeof GatewaysV2Schema>;
export type TGatewaysV2Insert = Omit<z.input<typeof GatewaysV2Schema>, TImmutableDBKeys>;
export type TGatewaysV2Update = Partial<Omit<z.input<typeof GatewaysV2Schema>, TImmutableDBKeys>>;
3 changes: 2 additions & 1 deletion backend/src/db/schemas/identity-kubernetes-auths.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ export const IdentityKubernetesAuthsSchema = z.object({
encryptedKubernetesCaCertificate: zodBuffer.nullable().optional(),
gatewayId: z.string().uuid().nullable().optional(),
accessTokenPeriod: z.coerce.number().default(0),
tokenReviewMode: z.string().default("api")
tokenReviewMode: z.string().default("api"),
gatewayV2Id: z.string().uuid().nullable().optional()
});

export type TIdentityKubernetesAuths = z.infer<typeof IdentityKubernetesAuthsSchema>;
Expand Down
5 changes: 5 additions & 0 deletions backend/src/db/schemas/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export * from "./folder-commits";
export * from "./folder-tree-checkpoint-resources";
export * from "./folder-tree-checkpoints";
export * from "./gateways";
export * from "./gateways-v2";
export * from "./git-app-install-sessions";
export * from "./git-app-org";
export * from "./github-org-sync-configs";
Expand All @@ -57,6 +58,7 @@ export * from "./identity-token-auths";
export * from "./identity-ua-client-secrets";
export * from "./identity-universal-auths";
export * from "./incident-contacts";
export * from "./instance-relay-config";
export * from "./integration-auths";
export * from "./integrations";
export * from "./internal-certificate-authorities";
Expand All @@ -76,7 +78,9 @@ export * from "./models";
export * from "./oidc-configs";
export * from "./org-bots";
export * from "./org-gateway-config";
export * from "./org-gateway-config-v2";
export * from "./org-memberships";
export * from "./org-relay-config";
export * from "./org-roles";
export * from "./organizations";
export * from "./pki-alerts";
Expand All @@ -97,6 +101,7 @@ export * from "./project-user-additional-privilege";
export * from "./project-user-membership-roles";
export * from "./projects";
export * from "./rate-limit";
export * from "./relays";
export * from "./resource-metadata";
export * from "./saml-configs";
export * from "./scim-tokens";
Expand Down
Loading
Loading