From 95e94ff9de2220e165b619e934d6fe50b89e09d9 Mon Sep 17 00:00:00 2001 From: malo-octo Date: Mon, 8 Jan 2024 17:48:38 +0100 Subject: [PATCH] feat: add keycloak secrets --- src/pages/api/auth/[...nextauth].ts | 11 ++++- vault/VaultModule.js | 65 +++++++++++++++++++++++++++++ vault/package.json | 19 +++++++++ vault/tsconfig.json | 16 +++++++ 4 files changed, 109 insertions(+), 2 deletions(-) create mode 100644 vault/VaultModule.js create mode 100644 vault/package.json create mode 100644 vault/tsconfig.json diff --git a/src/pages/api/auth/[...nextauth].ts b/src/pages/api/auth/[...nextauth].ts index dafd55d2..58dad88a 100644 --- a/src/pages/api/auth/[...nextauth].ts +++ b/src/pages/api/auth/[...nextauth].ts @@ -3,9 +3,16 @@ import { Account } from "next-auth"; import { User } from "next-auth"; import { JWT } from "next-auth/jwt"; import KeycloakProvider from "next-auth/providers/keycloak"; +import VaultModule from "../../../../vault/VaultModule" import { refreshAccessToken } from "../../../lib/auth"; + +const vaultModule = new VaultModule("integrated"); +const keycloakClientId = vaultModule.readSecret("keycloak_client_id") +const keycloakClientSecret = vaultModule.readSecret("eycloak_client_secret") + + interface ExtendedToken extends JWT { accessToken: string; refreshToken: string; @@ -18,8 +25,8 @@ export default NextAuth({ debug: true, providers: [ KeycloakProvider({ - clientId: process.env.KEYCLOAK_CLIENT_ID ?? "", - clientSecret: process.env.KEYCLOAK_CLIENT_SECRET ?? "", + clientId: keycloakClientId ?? "", + clientSecret: keycloakClientSecret ?? "", issuer: process.env.KEYCLOAK_URL ?? "", }), ], diff --git a/vault/VaultModule.js b/vault/VaultModule.js new file mode 100644 index 00000000..a238e4c6 --- /dev/null +++ b/vault/VaultModule.js @@ -0,0 +1,65 @@ +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const fs = __importStar(require("fs")); +const vault = require("node-vault"); +class VaultModule { + constructor(vaultRole) { + this.vaultClient = vault({ + apiVersion: 'v1', + endpoint: "http://vault.vault-dev.svc:8200", + }); + this.vaultRole = vaultRole; + this.isKubelogged = false; + } + async readSecret(path) { + const JWT_TOKEN_FILE = "/var/run/secrets/kubernetes.io/serviceaccount/token"; + const jwt = fs.readFileSync(JWT_TOKEN_FILE); + if (!this.isKubelogged) { + try { + const result = await this.vaultClient.kubernetesLogin({ + "role": this.vaultRole, + "jwt": jwt.toString() + }); + this.vaultClient.token = result.auth.client_token; + } + catch (error) { + console.error('Error authenticating to vault instance:', error.message); + throw error; + } + this.isKubelogged = true; + } + try { + const { data } = await this.vaultClient.read(path); + const obj = Object.keys(data.data); + return data.data[obj[0]]; + } + catch (error) { + console.error('Error reading secret:', error.message); + throw error; + } + } +} +exports.default = VaultModule; diff --git a/vault/package.json b/vault/package.json new file mode 100644 index 00000000..cc967c28 --- /dev/null +++ b/vault/package.json @@ -0,0 +1,19 @@ +{ + "name": "vault-integrated", + "version": "1.0.0", + "description": "Vault integrated for template application", + "main": "app.js", + "scripts": { + "build": "tsc", + "start": "node index.ts" + }, + "dependencies": { + "node-vault": "^0.10.2" + }, + "devDependencies": { + "typescript": "5.1.6" + }, + "engines": { + "node": "18.11.17" + } +} diff --git a/vault/tsconfig.json b/vault/tsconfig.json new file mode 100644 index 00000000..8271fbdc --- /dev/null +++ b/vault/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "target": "es2018", + "module": "commonjs", + "outDir": ".", + "rootDir": ".", + "strict": true, + "esModuleInterop": true + }, + "include": [ + "*.ts" + ], + "exclude": [ + "node_modules" + ] +}