mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-08 18:28:12 +00:00
Checkpoint argon2id test to generate blind index
This commit is contained in:
@@ -1,7 +1,9 @@
|
|||||||
import { Request, Response } from 'express';
|
import { Request, Response } from 'express';
|
||||||
|
import { Types } from 'mongoose';
|
||||||
import {
|
import {
|
||||||
Secret
|
Secret
|
||||||
} from '../../models';
|
} from '../../models';
|
||||||
|
import crypto from 'crypto';
|
||||||
|
|
||||||
// TODO: modularize argon2id
|
// TODO: modularize argon2id
|
||||||
import * as argon2 from 'argon2';
|
import * as argon2 from 'argon2';
|
||||||
@@ -47,13 +49,32 @@ export const createSecret = async (req: Request, res: Response) => {
|
|||||||
const {
|
const {
|
||||||
workspaceId,
|
workspaceId,
|
||||||
environment,
|
environment,
|
||||||
value
|
value,
|
||||||
|
type
|
||||||
} = req.body;
|
} = req.body;
|
||||||
|
|
||||||
//
|
// use workspace salt
|
||||||
// use bot to encrypt value
|
const randomBytes = crypto.randomBytes(16);
|
||||||
// BotService.encryptSymmetric(value)
|
|
||||||
|
|
||||||
|
// generate blind index
|
||||||
|
// TODO 1: abstract away into create blind index function
|
||||||
|
// TODO 2: create a get blind index function
|
||||||
|
const secretBlindIndex = (await argon2.hash(secretName, {
|
||||||
|
type: argon2.argon2id,
|
||||||
|
salt: randomBytes,
|
||||||
|
saltLength: 16, // default 16 bytes
|
||||||
|
memoryCost: 65536, // default pool of 64 MiB per thread.
|
||||||
|
hashLength: 32,
|
||||||
|
parallelism: 1,
|
||||||
|
raw: true
|
||||||
|
})).toString('base64');
|
||||||
|
|
||||||
|
// const secret = await new Secret({
|
||||||
|
// workspace: new Types.ObjectId(workspaceId),
|
||||||
|
// environment,
|
||||||
|
// type,
|
||||||
|
// secretBlindIndex
|
||||||
|
// }).save();
|
||||||
|
|
||||||
return res.status(200).send({
|
return res.status(200).send({
|
||||||
|
|
||||||
|
|||||||
@@ -61,6 +61,9 @@ import {
|
|||||||
environment as v2EnvironmentRouter,
|
environment as v2EnvironmentRouter,
|
||||||
tags as v2TagsRouter,
|
tags as v2TagsRouter,
|
||||||
} from './routes/v2';
|
} from './routes/v2';
|
||||||
|
import {
|
||||||
|
secrets as v3SecretsRouter
|
||||||
|
} from './routes/v3';
|
||||||
import { healthCheck } from './routes/status';
|
import { healthCheck } from './routes/status';
|
||||||
import { getLogger } from './utils/logger';
|
import { getLogger } from './utils/logger';
|
||||||
import { RouteNotFoundError } from './utils/errors';
|
import { RouteNotFoundError } from './utils/errors';
|
||||||
@@ -121,7 +124,7 @@ const main = async () => {
|
|||||||
app.use('/api/v1/workspace', eeWorkspaceRouter);
|
app.use('/api/v1/workspace', eeWorkspaceRouter);
|
||||||
app.use('/api/v1/action', eeActionRouter);
|
app.use('/api/v1/action', eeActionRouter);
|
||||||
|
|
||||||
// v1 routes
|
// v1 routes (default)
|
||||||
app.use('/api/v1/signup', v1SignupRouter);
|
app.use('/api/v1/signup', v1SignupRouter);
|
||||||
app.use('/api/v1/auth', v1AuthRouter);
|
app.use('/api/v1/auth', v1AuthRouter);
|
||||||
app.use('/api/v1/bot', v1BotRouter);
|
app.use('/api/v1/bot', v1BotRouter);
|
||||||
@@ -140,7 +143,7 @@ const main = async () => {
|
|||||||
app.use('/api/v1/integration', v1IntegrationRouter);
|
app.use('/api/v1/integration', v1IntegrationRouter);
|
||||||
app.use('/api/v1/integration-auth', v1IntegrationAuthRouter);
|
app.use('/api/v1/integration-auth', v1IntegrationAuthRouter);
|
||||||
|
|
||||||
// v2 routes
|
// v2 routes (improvements)
|
||||||
app.use('/api/v2/signup', v2SignupRouter);
|
app.use('/api/v2/signup', v2SignupRouter);
|
||||||
app.use('/api/v2/auth', v2AuthRouter);
|
app.use('/api/v2/auth', v2AuthRouter);
|
||||||
app.use('/api/v2/users', v2UsersRouter);
|
app.use('/api/v2/users', v2UsersRouter);
|
||||||
@@ -154,6 +157,9 @@ const main = async () => {
|
|||||||
app.use('/api/v2/service-accounts', v2ServiceAccountsRouter); // new
|
app.use('/api/v2/service-accounts', v2ServiceAccountsRouter); // new
|
||||||
app.use('/api/v2/api-key', v2APIKeyDataRouter);
|
app.use('/api/v2/api-key', v2APIKeyDataRouter);
|
||||||
|
|
||||||
|
// v3 routes (experimental)
|
||||||
|
app.use('/api/v3/secrets', v3SecretsRouter);
|
||||||
|
|
||||||
// api docs
|
// api docs
|
||||||
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerFile))
|
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerFile))
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import Membership, { IMembership } from './membership';
|
|||||||
import MembershipOrg, { IMembershipOrg } from './membershipOrg';
|
import MembershipOrg, { IMembershipOrg } from './membershipOrg';
|
||||||
import Organization, { IOrganization } from './organization';
|
import Organization, { IOrganization } from './organization';
|
||||||
import Secret, { ISecret } from './secret';
|
import Secret, { ISecret } from './secret';
|
||||||
|
import SecretBlindIndexData, { ISecretBlindIndexData } from './secretBlindIndexData';
|
||||||
import ServiceToken, { IServiceToken } from './serviceToken';
|
import ServiceToken, { IServiceToken } from './serviceToken';
|
||||||
import ServiceAccount, { IServiceAccount } from './serviceAccount'; // new
|
import ServiceAccount, { IServiceAccount } from './serviceAccount'; // new
|
||||||
import ServiceAccountKey, { IServiceAccountKey } from './serviceAccountKey'; // new
|
import ServiceAccountKey, { IServiceAccountKey } from './serviceAccountKey'; // new
|
||||||
@@ -45,6 +46,8 @@ export {
|
|||||||
IOrganization,
|
IOrganization,
|
||||||
Secret,
|
Secret,
|
||||||
ISecret,
|
ISecret,
|
||||||
|
SecretBlindIndexData,
|
||||||
|
ISecretBlindIndexData,
|
||||||
ServiceToken,
|
ServiceToken,
|
||||||
IServiceToken,
|
IServiceToken,
|
||||||
ServiceAccount,
|
ServiceAccount,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Schema, model, Types } from 'mongoose';
|
import { Schema, model, Types, Document } from 'mongoose';
|
||||||
import {
|
import {
|
||||||
SECRET_SHARED,
|
SECRET_SHARED,
|
||||||
SECRET_PERSONAL,
|
SECRET_PERSONAL,
|
||||||
@@ -11,6 +11,7 @@ export interface ISecret {
|
|||||||
type: string;
|
type: string;
|
||||||
user: Types.ObjectId;
|
user: Types.ObjectId;
|
||||||
environment: string;
|
environment: string;
|
||||||
|
secretBlindIndex?: string;
|
||||||
secretKeyCiphertext: string;
|
secretKeyCiphertext: string;
|
||||||
secretKeyIV: string;
|
secretKeyIV: string;
|
||||||
secretKeyTag: string;
|
secretKeyTag: string;
|
||||||
@@ -57,6 +58,9 @@ const secretSchema = new Schema<ISecret>(
|
|||||||
type: String,
|
type: String,
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
|
secretBlindIndex: {
|
||||||
|
type: String
|
||||||
|
},
|
||||||
secretKeyCiphertext: {
|
secretKeyCiphertext: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true
|
required: true
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import { Schema, model, Types, Document } from 'mongoose';
|
||||||
|
|
||||||
|
export interface ISecretBlindIndexData {
|
||||||
|
_id: Types.ObjectId;
|
||||||
|
workspace: Types.ObjectId;
|
||||||
|
encryptedSalt: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const secretBlindIndexDataSchema = new Schema<ISecretBlindIndexData>(
|
||||||
|
{
|
||||||
|
workspace: {
|
||||||
|
type: Schema.Types.ObjectId,
|
||||||
|
ref: 'Workspace',
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
encryptedSalt: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const SecretBlindIndexData = model<ISecretBlindIndexData>('SecretBlindIndexData', secretBlindIndexDataSchema);
|
||||||
|
|
||||||
|
export default SecretBlindIndexData;
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
import secrets from './secrets';
|
||||||
|
|
||||||
|
export {
|
||||||
|
secrets
|
||||||
|
}
|
||||||
@@ -20,13 +20,13 @@ router.post(
|
|||||||
'/:secretName',
|
'/:secretName',
|
||||||
body('workspaceId').exists().isString().trim(),
|
body('workspaceId').exists().isString().trim(),
|
||||||
body('environment').exists().isString().trim(),
|
body('environment').exists().isString().trim(),
|
||||||
body('value').exists().isString().trim(),
|
body('secretKeyCiphertext').exists().isString().trim(),
|
||||||
body('secretKeyCiphertext').optional().isString().trim(),
|
body('secretKeyIV').exists().isString().trim(),
|
||||||
body('secretKeyIV').optional().isString().trim(),
|
body('secretKeyTag').exists().isString().trim(),
|
||||||
body('secretKeyTag').optional().isString().trim(),
|
body('secretValueCiphertext').exists().isString().trim(),
|
||||||
body('secretValueCiphertext').optional().isString().trim(),
|
body('secretValueIV').exists().isString().trim(),
|
||||||
body('secretValueIV').optional().isString().trim(),
|
body('secretValueTag').exists().isString().trim(),
|
||||||
body('secretValueTag').optional().isString().trim(),
|
validateRequest,
|
||||||
secretsController.createSecret
|
secretsController.createSecret
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
// WIP
|
||||||
|
import { Types } from 'mongoose';
|
||||||
|
|
||||||
|
class SecretService {
|
||||||
|
static async createSecretBlindIndex({
|
||||||
|
secretName,
|
||||||
|
workspaceId,
|
||||||
|
}: {
|
||||||
|
secretName: string;
|
||||||
|
workspaceId: Types.ObjectId;
|
||||||
|
}) {
|
||||||
|
// TODO
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static async getSecretBlindIndex({
|
||||||
|
secretName,
|
||||||
|
workspaceId
|
||||||
|
}: {
|
||||||
|
secretName: string;
|
||||||
|
workspaceId: Types.ObjectId;
|
||||||
|
}) {
|
||||||
|
// TODO
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user