Skip to content

Commit

Permalink
Cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
mattschoch committed Feb 28, 2024
1 parent 21d5085 commit 62ae0cc
Show file tree
Hide file tree
Showing 8 changed files with 38 additions and 37 deletions.
4 changes: 2 additions & 2 deletions apps/policy-engine/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,14 @@ policy-engine/db/create-migration:
# project and resolve its path aliases before running the vanilla JavaScript
# seed entry point.
policy-engine/db/seed:
make policy-engine/build/script
npx dotenv -e ${POLICY_ENGINE_PROJECT_DIR}/.env -- \
node dist/out-tsc/${POLICY_ENGINE_PROJECT_DIR}/src/shared/module/persistence/seed.js
ts-node -r tsconfig-paths/register --project ${POLICY_ENGINE_PROJECT_DIR}/tsconfig.app.json ${POLICY_ENGINE_PROJECT_DIR}/src/shared/module/persistence/seed.ts


# === Testing ===

policy-engine/test/type:
make policy-engine/db/generate-types
npx tsc \
--project ${POLICY_ENGINE_PROJECT_DIR}/tsconfig.app.json \
--noEmit
Expand Down
2 changes: 1 addition & 1 deletion apps/policy-engine/src/app/__test__/e2e/admin.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import { readFileSync, unlinkSync } from 'fs'
import { mock } from 'jest-mock-extended'
import request from 'supertest'
import { AppModule } from '../../../app/app.module'
import { load } from '../../../policy-engine.config'
import { Organization } from '../../../shared/types/entities.types'
import { Criterion, Then, TimeWindow } from '../../../shared/types/policy.type'
import { load } from '../../app.config'
import { EntityRepository } from '../../persistence/repository/entity.repository'

const REQUEST_HEADER_ORG_ID = 'x-org-id'
Expand Down
33 changes: 17 additions & 16 deletions apps/policy-engine/src/keyring/core/keyring.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const AUTH_TAG_LENGTH = 16
export class KeyringService implements OnApplicationBootstrap {
private logger = new Logger(KeyringService.name)

private engineUid: string
private engineId: string

private kek: Buffer

Expand All @@ -25,34 +25,34 @@ export class KeyringService implements OnApplicationBootstrap {
private keyringRepository: KeyringRepository,
@Inject(ConfigService) configService: ConfigService<Config, true>
) {
this.engineUid = configService.get('engineUid', { infer: true })
this.masterPassword = configService.get('masterPassword', { infer: true })
this.engineId = configService.get('engine.id', { infer: true })
this.masterPassword = configService.get('engine.masterPassword', { infer: true })
}

async onApplicationBootstrap(): Promise<void> {
this.logger.log('Keyring Service boot')
let engine = await this.keyringRepository.getEngine(this.engineUid)
let engine = await this.keyringRepository.getEngine(this.engineId)

// Derive the Key Encryption Key (KEK) from the master password using PBKDF2
this.kek = this.deriveKek(this.masterPassword)
this.kek = this.deriveKeyEncryptionKey(this.masterPassword)

if (!engine) {
// New Engine, set it up
engine = await this.firstTimeSetup()
}

this.masterKey = this.decryptWithKey(engine.masterKey, this.kek)
this.adminApiKey = this.decryptWithKey(engine.adminApiKey, this.kek)
this.masterKey = this.decryptWithKey(this.kek, engine.masterKey)
this.adminApiKey = this.decryptWithKey(this.kek, engine.adminApiKey)
}

private deriveKek(password: string): Buffer {
private deriveKeyEncryptionKey(password: string): Buffer {
// Derive the Key Encryption Key (KEK) from the master password using PBKDF2
const kek = crypto.pbkdf2Sync(password.normalize(), this.engineUid.normalize(), 1000000, 32, 'sha256')
this.logger.log('Derived KEK', { kek: kek.toString('hex') })
const kek = crypto.pbkdf2Sync(password.normalize(), this.engineId.normalize(), 1000000, 32, 'sha256')
this.logger.log('Derived KEK', { kek: kek.toString('hex') }) // TODO: Sanitize
return kek
}

decryptWithKey(encryptedString: string, key: Buffer): Buffer {
decryptWithKey(key: Buffer, encryptedString: string): Buffer {
const encryptedBuffer = Buffer.from(encryptedString, 'hex')
// IV and AuthTag are prepend/appended, so slice them off
const iv = encryptedBuffer.subarray(0, IV_LENGTH)
Expand All @@ -68,7 +68,7 @@ export class KeyringService implements OnApplicationBootstrap {
return decrypted
}

encryptWithKey(data: Buffer, key: Buffer): string {
encryptWithKey(key: Buffer, data: Buffer): string {
const iv = crypto.randomBytes(IV_LENGTH)
const cipher = crypto.createCipheriv('aes-256-gcm', key, iv, { authTagLength: AUTH_TAG_LENGTH })
let encrypted = cipher.update(data)
Expand All @@ -88,13 +88,14 @@ export class KeyringService implements OnApplicationBootstrap {
const adminApiKeyBuffer = crypto.randomBytes(32)

// Encrypt the Master Key (MK) with the Key Encryption Key (KEK)
const encryptedMk = this.encryptWithKey(mkBuffer, this.kek)
const encryptedApiKey = this.encryptWithKey(adminApiKeyBuffer, this.kek)
const encryptedMk = this.encryptWithKey(this.kek, mkBuffer)
const encryptedApiKey = this.encryptWithKey(this.kek, adminApiKeyBuffer)

// Save the Result.
const engine = await this.keyringRepository.createEngine(this.engineUid, encryptedMk, encryptedApiKey)
const engine = await this.keyringRepository.createEngine(this.engineId, encryptedMk, encryptedApiKey)

this.logger.log('Engine Initial Setup Complete')
// TODO: Print this to a console in a better way; may not even like this.
this.logger.log('Admin API Key -- DO NOT LOSE THIS', adminApiKeyBuffer.toString('hex'))
return engine
}
Expand All @@ -107,7 +108,7 @@ export class KeyringService implements OnApplicationBootstrap {
deriveContentEncryptionKey(keyId: string) {
// Derive a CEK from the MK+keyId using HKDF
const cek = crypto.hkdfSync('sha256', this.masterKey, keyId, 'content', 32)
this.logger.log('Derived KEK', { cek: Buffer.from(cek).toString('hex') })
this.logger.log('Derived KEK', { cek: Buffer.from(cek).toString('hex') }) // TODO: Sanitize
return Buffer.from(cek)
}
}
Original file line number Diff line number Diff line change
@@ -1,28 +1,24 @@
import { Injectable, Logger, OnModuleInit } from '@nestjs/common'
import { Injectable, Logger } from '@nestjs/common'
import { PrismaService } from '../../../shared/module/persistence/service/prisma.service'

@Injectable()
export class KeyringRepository implements OnModuleInit {
export class KeyringRepository {
private logger = new Logger(KeyringRepository.name)

constructor(private prismaService: PrismaService) {}

async onModuleInit() {
this.logger.log('KeyringRepository initialized')
}

async getEngine(engineUid: string) {
async getEngine(engineId: string) {
return this.prismaService.engine.findUnique({
where: {
uid: engineUid
id: engineId
}
})
}

async createEngine(engineUid: string, masterKey: string, adminApiKey: string) {
async createEngine(engineId: string, masterKey: string, adminApiKey: string) {
return this.prismaService.engine.create({
data: {
uid: engineUid,
id: engineId,
masterKey,
adminApiKey
}
Expand Down
12 changes: 8 additions & 4 deletions apps/policy-engine/src/policy-engine.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ const ConfigSchema = z.object({
database: z.object({
url: z.string().startsWith('postgresql:')
}),
engineUid: z.string().optional(),
masterPassword: z.string().optional()
engine: z.object({
id: z.string(),
masterPassword: z.string()
})
})

export type Config = z.infer<typeof ConfigSchema>
Expand All @@ -25,8 +27,10 @@ export const load = (): Config => {
database: {
url: process.env.POLICY_ENGINE_DATABASE_URL
},
engineUid: process.env.ENGINE_UID,
masterPassword: process.env.MASTER_PASSWORD
engine: {
id: process.env.ENGINE_UID,
masterPassword: process.env.MASTER_PASSWORD
}
})

if (result.success) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
-- CreateTable
CREATE TABLE "engine" (
"uid" TEXT NOT NULL,
"id" TEXT NOT NULL,
"master_key" TEXT NOT NULL,
"admin_api_key" TEXT NOT NULL,

CONSTRAINT "engine_pkey" PRIMARY KEY ("uid")
CONSTRAINT "engine_pkey" PRIMARY KEY ("id")
);
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ datasource db {
}

model Engine {
uid String @id
id String @id
masterKey String @map("master_key")
adminApiKey String @map("admin_api_key")
Expand Down
2 changes: 1 addition & 1 deletion apps/policy-engine/src/shared/module/persistence/seed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Engine, PrismaClient } from '@prisma/client/policy-engine'
const prisma = new PrismaClient()

const engine: Engine = {
uid: '7d704a62-d15e-4382-a826-1eb41563043b',
id: '7d704a62-d15e-4382-a826-1eb41563043b',
adminApiKey: 'admin-api-key-xxx',
masterKey: 'master-key-xxx'
}
Expand Down

0 comments on commit 62ae0cc

Please sign in to comment.