Applying Custom Policies
The Policy Engine lets users define custom validation and modification rules using TypeScript. It helps ensure compliance, security, and consistency by enforcing rules and dynamically updating manifests before deployment.
Validation Policies
Validation policies ensure that only compliant configurations are deployed. These policies evaluate Truefoundry manifests and prevent deployments that do not meet specific conditions. Some common use cases include:
- Enforcing readiness and liveness probes for all production services.
- Enforcing spot instance on dev environment for cost savings.
- Enforcing auto shutdown for all dev services.
Here is a sample policy which enforces auto-shutdown for all services deployed in workspace with env name "dev"
import { ValidationInput, ValidationError } from '@src/types';
export function validate(validationInput: ValidationInput): void {
const { manifest, context } = validationInput;
const envName = context.envName;
if(manifest.type !== 'service') return;
if (envName === 'dev') {
if (!manifest.auto_shutdown) {
throw new ValidationError(
'Auto shutdown is required for the dev environment.'
);
}
}
}
Mutation Policies
Mutation policies let you automatically modify Kubernetes manifests before they're applied to the cluster. You can define custom rules by writing code to change these manifests based on your needs—no need to use Kustomize.
Common use cases include:
- Setting node affinity for certain workloads like SSH servers or notebooks
- Adding default secrets, volume mounts, or environment variables to services and jobs
- Updating image prefixes to match internal repository setups
These policies run one after another, in a specific order. Policies with lower order values are applied first.
Here is a sample mutation policy which mutates the registry for the images to private jfrog repository.
import { MutationInput, MutationOutput } from '@src/types';
export function mutate(mutationInput: MutationInput): MutationOutput {
const { generatedK8sManifests } = mutationInput;
if (mutationInput.context.inputManifest.type !== 'service') {
return { generatedK8sManifests };
}
if (generatedK8sManifests) {
for (const manifest of generatedK8sManifests) {
if (
manifest.kind === 'Deployment'
) {
manifest.spec.template.spec.containers.forEach((container: any) => {
if (container.image.startsWith('tfy.jfrog.io')) {
container.image = container.image.replace(
'tfy.jfrog.io',
'private.tfy.jfrog.io'
);
}
});
}
}
}
return { generatedK8sManifests };
}
Both validation and mutation policies are executed in a sandbox environment before deployment to ensure secure and isolated execution.
Creating a policy
Policies must be written in TypeScript. To write and test your policy code, refer to this repository: https://github.com/truefoundry/tfy-typescript-policy
- Write your policy logic in
src/policy.ts
. - Import required models from
src/models.ts
.
Use type definitions from src/types.ts
to ensure type-safe code.
Test your policy locally using:
npx ts-node local_run.ts
You can find policy code examples for common use cases in this folder: https://github.com/truefoundry/tfy-typescript-policy/tree/main/examples
Note: When creating/updating your policy, only provide the contents of policy.ts in the Policy Code input field.
Registering Your Policy on Truefoundry
After writing your policy code, you can register your policy on Truefoundry by following these steps:
1. Enter Policy Details
Provide the name and description of the policy.
2. Select Policy Action
-
Validate: Ensures manifests meet certain conditions.
-
Mutate: Modifies manifests before applying them.
Mutate policies have an order associated that determines their execution order.
3. Choose Policy Mode
- Audit: Logs policy executions but does not block deployments. Ideally when creating a policy, users should put it in
- Enforce: Blocks deployments if the policy evaluation fails.
- Disabled: The policy is ignored.
4. TypeScript Code:
Paste the typescript code that you wrote in previous step.
5. Define Entities
Specify the resource types the policy should apply to. (service, job, ssh-server etc)
6. Set Filters
Use Clusters, Environments, and Workspaces to filter applicable manifests. [by default it applies to all manifests]
Filters expect the name (not FQN) of workspaces, environments, and clusters.
Here is how it looks on UI:


You can find all Policies registered and see their specific runs:

You can also check the diff for a mutation policy also:

Updated 1 day ago