mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-08 08:27:53 +00:00
feat: updated backend for identity auth with reviewer optional
This commit is contained in:
@@ -0,0 +1,19 @@
|
|||||||
|
import { Knex } from "knex";
|
||||||
|
|
||||||
|
import { TableName } from "../schemas";
|
||||||
|
|
||||||
|
export async function up(knex: Knex): Promise<void> {
|
||||||
|
const hasReviewerJwtCol = await knex.schema.hasColumn(
|
||||||
|
TableName.IdentityKubernetesAuth,
|
||||||
|
"encryptedKubernetesTokenReviewerJwt"
|
||||||
|
);
|
||||||
|
if (hasReviewerJwtCol) {
|
||||||
|
await knex.schema.alterTable(TableName.IdentityKubernetesAuth, (t) => {
|
||||||
|
t.binary("encryptedKubernetesTokenReviewerJwt").nullable().alter();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function down(): Promise<void> {
|
||||||
|
// we can't make it back to non nullable, it will fail
|
||||||
|
}
|
||||||
@@ -28,7 +28,7 @@ export const IdentityKubernetesAuthsSchema = z.object({
|
|||||||
allowedNamespaces: z.string(),
|
allowedNamespaces: z.string(),
|
||||||
allowedNames: z.string(),
|
allowedNames: z.string(),
|
||||||
allowedAudience: z.string(),
|
allowedAudience: z.string(),
|
||||||
encryptedKubernetesTokenReviewerJwt: zodBuffer,
|
encryptedKubernetesTokenReviewerJwt: zodBuffer.nullable().optional(),
|
||||||
encryptedKubernetesCaCertificate: zodBuffer.nullable().optional()
|
encryptedKubernetesCaCertificate: zodBuffer.nullable().optional()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -244,7 +244,7 @@ export const KUBERNETES_AUTH = {
|
|||||||
kubernetesHost: "The host string, host:port pair, or URL to the base of the Kubernetes API server.",
|
kubernetesHost: "The host string, host:port pair, or URL to the base of the Kubernetes API server.",
|
||||||
caCert: "The PEM-encoded CA cert for the Kubernetes API server.",
|
caCert: "The PEM-encoded CA cert for the Kubernetes API server.",
|
||||||
tokenReviewerJwt:
|
tokenReviewerJwt:
|
||||||
"The long-lived service account JWT token for Infisical to access the TokenReview API to validate other service account JWT tokens submitted by applications/pods.",
|
"Optional JWT token for accessing Kubernetes TokenReview API. If provided, this long-lived token will be used to validate service account tokens during authentication. If omitted, the client's own JWT will be used instead, which requires the client to have the system:auth-delegator ClusterRole binding.",
|
||||||
allowedNamespaces:
|
allowedNamespaces:
|
||||||
"The comma-separated list of trusted namespaces that service accounts must belong to authenticate with Infisical.",
|
"The comma-separated list of trusted namespaces that service accounts must belong to authenticate with Infisical.",
|
||||||
allowedNames: "The comma-separated list of trusted service account names that can authenticate with Infisical.",
|
allowedNames: "The comma-separated list of trusted service account names that can authenticate with Infisical.",
|
||||||
@@ -260,7 +260,7 @@ export const KUBERNETES_AUTH = {
|
|||||||
kubernetesHost: "The new host string, host:port pair, or URL to the base of the Kubernetes API server.",
|
kubernetesHost: "The new host string, host:port pair, or URL to the base of the Kubernetes API server.",
|
||||||
caCert: "The new PEM-encoded CA cert for the Kubernetes API server.",
|
caCert: "The new PEM-encoded CA cert for the Kubernetes API server.",
|
||||||
tokenReviewerJwt:
|
tokenReviewerJwt:
|
||||||
"The new long-lived service account JWT token for Infisical to access the TokenReview API to validate other service account JWT tokens submitted by applications/pods.",
|
"Optional JWT token for accessing Kubernetes TokenReview API. If provided, this long-lived token will be used to validate service account tokens during authentication. If omitted, the client's own JWT will be used instead, which requires the client to have the system:auth-delegator ClusterRole binding.",
|
||||||
allowedNamespaces:
|
allowedNamespaces:
|
||||||
"The new comma-separated list of trusted namespaces that service accounts must belong to authenticate with Infisical.",
|
"The new comma-separated list of trusted namespaces that service accounts must belong to authenticate with Infisical.",
|
||||||
allowedNames: "The new comma-separated list of trusted service account names that can authenticate with Infisical.",
|
allowedNames: "The new comma-separated list of trusted service account names that can authenticate with Infisical.",
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ const IdentityKubernetesAuthResponseSchema = IdentityKubernetesAuthsSchema.pick(
|
|||||||
allowedAudience: true
|
allowedAudience: true
|
||||||
}).extend({
|
}).extend({
|
||||||
caCert: z.string(),
|
caCert: z.string(),
|
||||||
tokenReviewerJwt: z.string()
|
tokenReviewerJwt: z.string().optional().nullable()
|
||||||
});
|
});
|
||||||
|
|
||||||
export const registerIdentityKubernetesRouter = async (server: FastifyZodProvider) => {
|
export const registerIdentityKubernetesRouter = async (server: FastifyZodProvider) => {
|
||||||
@@ -98,7 +98,7 @@ export const registerIdentityKubernetesRouter = async (server: FastifyZodProvide
|
|||||||
.object({
|
.object({
|
||||||
kubernetesHost: z.string().trim().min(1).describe(KUBERNETES_AUTH.ATTACH.kubernetesHost),
|
kubernetesHost: z.string().trim().min(1).describe(KUBERNETES_AUTH.ATTACH.kubernetesHost),
|
||||||
caCert: z.string().trim().default("").describe(KUBERNETES_AUTH.ATTACH.caCert),
|
caCert: z.string().trim().default("").describe(KUBERNETES_AUTH.ATTACH.caCert),
|
||||||
tokenReviewerJwt: z.string().trim().min(1).describe(KUBERNETES_AUTH.ATTACH.tokenReviewerJwt),
|
tokenReviewerJwt: z.string().trim().optional().describe(KUBERNETES_AUTH.ATTACH.tokenReviewerJwt),
|
||||||
allowedNamespaces: z.string().describe(KUBERNETES_AUTH.ATTACH.allowedNamespaces), // TODO: validation
|
allowedNamespaces: z.string().describe(KUBERNETES_AUTH.ATTACH.allowedNamespaces), // TODO: validation
|
||||||
allowedNames: z.string().describe(KUBERNETES_AUTH.ATTACH.allowedNames),
|
allowedNames: z.string().describe(KUBERNETES_AUTH.ATTACH.allowedNames),
|
||||||
allowedAudience: z.string().describe(KUBERNETES_AUTH.ATTACH.allowedAudience),
|
allowedAudience: z.string().describe(KUBERNETES_AUTH.ATTACH.allowedAudience),
|
||||||
@@ -195,7 +195,7 @@ export const registerIdentityKubernetesRouter = async (server: FastifyZodProvide
|
|||||||
.object({
|
.object({
|
||||||
kubernetesHost: z.string().trim().min(1).optional().describe(KUBERNETES_AUTH.UPDATE.kubernetesHost),
|
kubernetesHost: z.string().trim().min(1).optional().describe(KUBERNETES_AUTH.UPDATE.kubernetesHost),
|
||||||
caCert: z.string().trim().optional().describe(KUBERNETES_AUTH.UPDATE.caCert),
|
caCert: z.string().trim().optional().describe(KUBERNETES_AUTH.UPDATE.caCert),
|
||||||
tokenReviewerJwt: z.string().trim().min(1).optional().describe(KUBERNETES_AUTH.UPDATE.tokenReviewerJwt),
|
tokenReviewerJwt: z.string().trim().nullable().optional().describe(KUBERNETES_AUTH.UPDATE.tokenReviewerJwt),
|
||||||
allowedNamespaces: z.string().optional().describe(KUBERNETES_AUTH.UPDATE.allowedNamespaces), // TODO: validation
|
allowedNamespaces: z.string().optional().describe(KUBERNETES_AUTH.UPDATE.allowedNamespaces), // TODO: validation
|
||||||
allowedNames: z.string().optional().describe(KUBERNETES_AUTH.UPDATE.allowedNames),
|
allowedNames: z.string().optional().describe(KUBERNETES_AUTH.UPDATE.allowedNames),
|
||||||
allowedAudience: z.string().optional().describe(KUBERNETES_AUTH.UPDATE.allowedAudience),
|
allowedAudience: z.string().optional().describe(KUBERNETES_AUTH.UPDATE.allowedAudience),
|
||||||
|
|||||||
@@ -84,6 +84,9 @@ export const identityKubernetesAuthServiceFactory = ({
|
|||||||
tokenReviewerJwt = decryptor({
|
tokenReviewerJwt = decryptor({
|
||||||
cipherTextBlob: identityKubernetesAuth.encryptedKubernetesTokenReviewerJwt
|
cipherTextBlob: identityKubernetesAuth.encryptedKubernetesTokenReviewerJwt
|
||||||
}).toString();
|
}).toString();
|
||||||
|
} else {
|
||||||
|
// if no token reviewer is provided means the incoming token has to act as reviewer
|
||||||
|
tokenReviewerJwt = serviceAccountJwt;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { data } = await axios
|
const { data } = await axios
|
||||||
@@ -291,7 +294,9 @@ export const identityKubernetesAuthServiceFactory = ({
|
|||||||
accessTokenTTL,
|
accessTokenTTL,
|
||||||
accessTokenNumUsesLimit,
|
accessTokenNumUsesLimit,
|
||||||
accessTokenTrustedIps: JSON.stringify(reformattedAccessTokenTrustedIps),
|
accessTokenTrustedIps: JSON.stringify(reformattedAccessTokenTrustedIps),
|
||||||
encryptedKubernetesTokenReviewerJwt: encryptor({ plainText: Buffer.from(tokenReviewerJwt) }).cipherTextBlob,
|
encryptedKubernetesTokenReviewerJwt: tokenReviewerJwt
|
||||||
|
? encryptor({ plainText: Buffer.from(tokenReviewerJwt) }).cipherTextBlob
|
||||||
|
: null,
|
||||||
encryptedKubernetesCaCertificate: encryptor({ plainText: Buffer.from(caCert) }).cipherTextBlob
|
encryptedKubernetesCaCertificate: encryptor({ plainText: Buffer.from(caCert) }).cipherTextBlob
|
||||||
},
|
},
|
||||||
tx
|
tx
|
||||||
@@ -387,10 +392,12 @@ export const identityKubernetesAuthServiceFactory = ({
|
|||||||
updateQuery.encryptedKubernetesCaCertificate = encryptor({ plainText: Buffer.from(caCert) }).cipherTextBlob;
|
updateQuery.encryptedKubernetesCaCertificate = encryptor({ plainText: Buffer.from(caCert) }).cipherTextBlob;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tokenReviewerJwt !== undefined) {
|
if (tokenReviewerJwt) {
|
||||||
updateQuery.encryptedKubernetesTokenReviewerJwt = encryptor({
|
updateQuery.encryptedKubernetesTokenReviewerJwt = encryptor({
|
||||||
plainText: Buffer.from(tokenReviewerJwt)
|
plainText: Buffer.from(tokenReviewerJwt)
|
||||||
}).cipherTextBlob;
|
}).cipherTextBlob;
|
||||||
|
} else if (tokenReviewerJwt === null) {
|
||||||
|
updateQuery.encryptedKubernetesTokenReviewerJwt = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const updatedKubernetesAuth = await identityKubernetesAuthDAL.updateById(identityKubernetesAuth.id, updateQuery);
|
const updatedKubernetesAuth = await identityKubernetesAuthDAL.updateById(identityKubernetesAuth.id, updateQuery);
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ export type TAttachKubernetesAuthDTO = {
|
|||||||
identityId: string;
|
identityId: string;
|
||||||
kubernetesHost: string;
|
kubernetesHost: string;
|
||||||
caCert: string;
|
caCert: string;
|
||||||
tokenReviewerJwt: string;
|
tokenReviewerJwt?: string;
|
||||||
allowedNamespaces: string;
|
allowedNamespaces: string;
|
||||||
allowedNames: string;
|
allowedNames: string;
|
||||||
allowedAudience: string;
|
allowedAudience: string;
|
||||||
@@ -24,7 +24,7 @@ export type TUpdateKubernetesAuthDTO = {
|
|||||||
identityId: string;
|
identityId: string;
|
||||||
kubernetesHost?: string;
|
kubernetesHost?: string;
|
||||||
caCert?: string;
|
caCert?: string;
|
||||||
tokenReviewerJwt?: string;
|
tokenReviewerJwt?: string | null;
|
||||||
allowedNamespaces?: string;
|
allowedNamespaces?: string;
|
||||||
allowedNames?: string;
|
allowedNames?: string;
|
||||||
allowedAudience?: string;
|
allowedAudience?: string;
|
||||||
|
|||||||
Reference in New Issue
Block a user