mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
Update permission implementation for ST V3
This commit is contained in:
@@ -110,14 +110,14 @@ export const getSecretsRaw = async (req: Request, res: Response) => {
|
||||
workspaceId: new Types.ObjectId(workspaceId),
|
||||
environment,
|
||||
secretPath,
|
||||
acceptedPermissions: [Permission.READ, Permission.READ_WRITE]
|
||||
requiredPermissions: [Permission.READ]
|
||||
});
|
||||
permissionCheckFn = (env: string, secPath: string) =>
|
||||
isValidScopeV3({
|
||||
authPayload: req.authData.authPayload as IServiceTokenDataV3,
|
||||
environment: env,
|
||||
secretPath: secPath,
|
||||
acceptedPermissions: [Permission.READ, Permission.READ_WRITE]
|
||||
requiredPermissions: [Permission.READ]
|
||||
});
|
||||
break;
|
||||
}
|
||||
@@ -213,7 +213,7 @@ export const getSecretByNameRaw = async (req: Request, res: Response) => {
|
||||
workspaceId: new Types.ObjectId(workspaceId),
|
||||
environment,
|
||||
secretPath,
|
||||
acceptedPermissions: [Permission.READ, Permission.READ_WRITE]
|
||||
requiredPermissions: [Permission.READ]
|
||||
});
|
||||
break;
|
||||
}
|
||||
@@ -285,7 +285,7 @@ export const createSecretRaw = async (req: Request, res: Response) => {
|
||||
workspaceId: new Types.ObjectId(workspaceId),
|
||||
environment,
|
||||
secretPath,
|
||||
acceptedPermissions: [Permission.READ_WRITE]
|
||||
requiredPermissions: [Permission.WRITE]
|
||||
});
|
||||
break;
|
||||
}
|
||||
@@ -384,7 +384,7 @@ export const updateSecretByNameRaw = async (req: Request, res: Response) => {
|
||||
workspaceId: new Types.ObjectId(workspaceId),
|
||||
environment,
|
||||
secretPath,
|
||||
acceptedPermissions: [Permission.READ_WRITE]
|
||||
requiredPermissions: [Permission.WRITE]
|
||||
});
|
||||
break;
|
||||
}
|
||||
@@ -464,7 +464,7 @@ export const deleteSecretByNameRaw = async (req: Request, res: Response) => {
|
||||
workspaceId: new Types.ObjectId(workspaceId),
|
||||
environment,
|
||||
secretPath,
|
||||
acceptedPermissions: [Permission.READ_WRITE]
|
||||
requiredPermissions: [Permission.WRITE]
|
||||
});
|
||||
break;
|
||||
}
|
||||
@@ -559,14 +559,14 @@ export const getSecrets = async (req: Request, res: Response) => {
|
||||
workspaceId: new Types.ObjectId(workspaceId),
|
||||
environment,
|
||||
secretPath,
|
||||
acceptedPermissions: [Permission.READ, Permission.READ_WRITE]
|
||||
requiredPermissions: [Permission.READ]
|
||||
});
|
||||
permissionCheckFn = (env: string, secPath: string) =>
|
||||
isValidScopeV3({
|
||||
authPayload: req.authData.authPayload as IServiceTokenDataV3,
|
||||
environment: env,
|
||||
secretPath: secPath,
|
||||
acceptedPermissions: [Permission.READ, Permission.READ_WRITE]
|
||||
requiredPermissions: [Permission.READ]
|
||||
});
|
||||
break;
|
||||
}
|
||||
@@ -644,7 +644,7 @@ export const getSecretByName = async (req: Request, res: Response) => {
|
||||
workspaceId: new Types.ObjectId(workspaceId),
|
||||
environment,
|
||||
secretPath,
|
||||
acceptedPermissions: [Permission.READ, Permission.READ_WRITE]
|
||||
requiredPermissions: [Permission.READ]
|
||||
});
|
||||
break;
|
||||
}
|
||||
@@ -717,7 +717,7 @@ export const createSecret = async (req: Request, res: Response) => {
|
||||
workspaceId: new Types.ObjectId(workspaceId),
|
||||
environment,
|
||||
secretPath,
|
||||
acceptedPermissions: [Permission.READ_WRITE]
|
||||
requiredPermissions: [Permission.WRITE]
|
||||
});
|
||||
break;
|
||||
}
|
||||
@@ -816,7 +816,7 @@ export const updateSecretByName = async (req: Request, res: Response) => {
|
||||
workspaceId: new Types.ObjectId(workspaceId),
|
||||
environment,
|
||||
secretPath,
|
||||
acceptedPermissions: [Permission.READ_WRITE]
|
||||
requiredPermissions: [Permission.WRITE]
|
||||
});
|
||||
break;
|
||||
}
|
||||
@@ -892,7 +892,7 @@ export const deleteSecretByName = async (req: Request, res: Response) => {
|
||||
workspaceId: new Types.ObjectId(workspaceId),
|
||||
environment,
|
||||
secretPath,
|
||||
acceptedPermissions: [Permission.READ_WRITE]
|
||||
requiredPermissions: [Permission.WRITE]
|
||||
});
|
||||
break;
|
||||
}
|
||||
@@ -950,7 +950,7 @@ export const createSecretByNameBatch = async (req: Request, res: Response) => {
|
||||
workspaceId: new Types.ObjectId(workspaceId),
|
||||
environment,
|
||||
secretPath,
|
||||
acceptedPermissions: [Permission.READ_WRITE]
|
||||
requiredPermissions: [Permission.WRITE]
|
||||
});
|
||||
break;
|
||||
}
|
||||
@@ -999,7 +999,7 @@ export const updateSecretByNameBatch = async (req: Request, res: Response) => {
|
||||
workspaceId: new Types.ObjectId(workspaceId),
|
||||
environment,
|
||||
secretPath,
|
||||
acceptedPermissions: [Permission.READ_WRITE]
|
||||
requiredPermissions: [Permission.WRITE]
|
||||
});
|
||||
break;
|
||||
}
|
||||
@@ -1048,7 +1048,7 @@ export const deleteSecretByNameBatch = async (req: Request, res: Response) => {
|
||||
workspaceId: new Types.ObjectId(workspaceId),
|
||||
environment,
|
||||
secretPath,
|
||||
acceptedPermissions: [Permission.READ_WRITE]
|
||||
requiredPermissions: [Permission.WRITE]
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -94,6 +94,7 @@ export const createServiceTokenData = async (req: Request, res: Response) => {
|
||||
user,
|
||||
workspace: new Types.ObjectId(workspaceId),
|
||||
publicKey,
|
||||
usageCount: 0,
|
||||
scopes,
|
||||
isActive,
|
||||
expiresAt
|
||||
|
||||
@@ -64,7 +64,7 @@ class EELicenseService {
|
||||
secretVersioning: true,
|
||||
pitRecovery: false,
|
||||
ipAllowlisting: false,
|
||||
rbac: true,
|
||||
rbac: false,
|
||||
customRateLimits: false,
|
||||
customAlerts: false,
|
||||
auditLogs: false,
|
||||
|
||||
@@ -249,7 +249,8 @@ export const getAuthSTDPayload = async ({
|
||||
isActive: true
|
||||
},
|
||||
{
|
||||
lastUsed: new Date()
|
||||
lastUsed: new Date(),
|
||||
$inc: { usageCount: 1 }
|
||||
},
|
||||
{
|
||||
new: true
|
||||
|
||||
@@ -69,12 +69,12 @@ export const isValidScopeV3 = ({
|
||||
authPayload,
|
||||
environment,
|
||||
secretPath,
|
||||
acceptedPermissions
|
||||
requiredPermissions
|
||||
}: {
|
||||
authPayload: IServiceTokenDataV3,
|
||||
environment: string,
|
||||
secretPath: string,
|
||||
acceptedPermissions: Permission[]
|
||||
requiredPermissions: Permission[]
|
||||
}) => {
|
||||
const { scopes } = authPayload;
|
||||
|
||||
@@ -84,7 +84,7 @@ export const isValidScopeV3 = ({
|
||||
scope.environment === environment
|
||||
);
|
||||
|
||||
if (validScope && !acceptedPermissions.includes(validScope.permission)) {
|
||||
if (validScope && !requiredPermissions.every(permission => validScope.permissions.includes(permission))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,13 +2,13 @@ import { Document, Schema, Types, model } from "mongoose";
|
||||
|
||||
export enum Permission {
|
||||
READ = "read",
|
||||
READ_WRITE = "readWrite"
|
||||
WRITE = "write"
|
||||
}
|
||||
|
||||
export interface Scope {
|
||||
environment: string;
|
||||
secretPath: string;
|
||||
permission: Permission;
|
||||
permissions: Permission[];
|
||||
}
|
||||
|
||||
export interface IServiceTokenDataV3 extends Document {
|
||||
@@ -19,6 +19,7 @@ export interface IServiceTokenDataV3 extends Document {
|
||||
publicKey: string;
|
||||
isActive: boolean;
|
||||
lastUsed?: Date;
|
||||
usageCount: number;
|
||||
expiresAt?: Date;
|
||||
scopes: Array<Scope>;
|
||||
}
|
||||
@@ -51,6 +52,11 @@ const serviceTokenDataV3Schema = new Schema(
|
||||
type: Date,
|
||||
required: false
|
||||
},
|
||||
usageCount: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
required: true
|
||||
},
|
||||
expiresAt: {
|
||||
type: Date,
|
||||
required: false,
|
||||
@@ -68,9 +74,10 @@ const serviceTokenDataV3Schema = new Schema(
|
||||
default: "/",
|
||||
required: true
|
||||
},
|
||||
permission: {
|
||||
type: String,
|
||||
enum: [Permission.READ, Permission.READ_WRITE],
|
||||
permissions: {
|
||||
type: [String],
|
||||
enum: [Permission.READ, Permission.WRITE],
|
||||
default: [Permission.READ],
|
||||
required: true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,13 +20,13 @@ import { isValidScopeV3 } from "../helpers";
|
||||
workspaceId,
|
||||
environment,
|
||||
secretPath = "/",
|
||||
acceptedPermissions
|
||||
requiredPermissions
|
||||
}: {
|
||||
serviceTokenData: IServiceTokenDataV3;
|
||||
workspaceId: Types.ObjectId;
|
||||
environment?: string;
|
||||
secretPath?: string;
|
||||
acceptedPermissions: Permission[];
|
||||
requiredPermissions: Permission[];
|
||||
}) => {
|
||||
|
||||
if (!serviceTokenData.workspace.equals(workspaceId)) {
|
||||
@@ -41,7 +41,7 @@ import { isValidScopeV3 } from "../helpers";
|
||||
authPayload: serviceTokenData,
|
||||
environment,
|
||||
secretPath,
|
||||
acceptedPermissions
|
||||
requiredPermissions
|
||||
});
|
||||
|
||||
if (!isValid) throw UnauthorizedRequestError({
|
||||
@@ -57,7 +57,7 @@ export const CreateServiceTokenV3 = z.object({
|
||||
publicKey: z.string().trim(),
|
||||
scopes: z
|
||||
.object({
|
||||
permission: z.enum(["read", "readWrite"]),
|
||||
permissions: z.enum(["read", "write"]).array(),
|
||||
environment: z.string().trim(),
|
||||
secretPath: z.string().trim()
|
||||
})
|
||||
@@ -78,7 +78,7 @@ export const UpdateServiceTokenV3 = z.object({
|
||||
isActive: z.boolean().optional(),
|
||||
scopes: z
|
||||
.object({
|
||||
permission: z.enum(["read", "readWrite"]),
|
||||
permissions: z.enum(["read", "write"]).array(),
|
||||
environment: z.string().trim(),
|
||||
secretPath: z.string().trim()
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user