Configuration
Configure ToolConfig, LLMConfig, and the Remediator custom resource.
The Remediator Agent is configured through three Kubernetes custom resources:
| Resource | Purpose |
|---|---|
| ToolConfig | Git provider credentials and PR defaults |
| LLMConfig | AI provider settings (Nirmata AI, AWS Bedrock, Azure OpenAI) |
| Remediator | What to scan, when to run, and what actions to take |
ToolConfig
ToolConfig defines how the agent authenticates with your Git provider and sets defaults for the pull requests it creates.
GitHub — Personal Access Token
kubectl create secret generic github-pat-token \
--from-literal=token=GITHUB_PAT_TOKEN \
--namespace nirmata
kubectl apply -f - <<EOF
apiVersion: serviceagents.nirmata.io/v1alpha1
kind: ToolConfig
metadata:
name: toolconfig-sample
namespace: nirmata
spec:
type: github
credentials:
method: pat
pat:
tokenSecretRef:
name: github-pat-token
namespace: nirmata
key: token
defaults:
git:
pullRequests:
branchPrefix: "remediation-"
titleTemplate: "[Auto-Remediation] Fix policy violations: "
commitMessageTemplate: "Auto-fix: Remediate policy violations: "
customLabels:
- "auto-remediation"
- "security"
systemLabels:
- "clusterName"
- "namespace"
EOF
```text
### GitHub — Nirmata GitHub App (Recommended)
Using the Nirmata GitHub App avoids managing secrets manually and provides automatic token rotation. Follow the [GitHub Authentication guide](../github-authentication/) to set up the App integration first.
```yaml
apiVersion: serviceagents.nirmata.io/v1alpha1
kind: ToolConfig
metadata:
name: toolconfig-sample
namespace: nirmata
spec:
type: github
credentials:
method: nirmata-app
defaults:
git:
pullRequests:
branchPrefix: "remediation-"
titleTemplate: "[Auto-Remediation] Fix policy violations: "
commitMessageTemplate: "Auto-fix: Remediate policy violations: "
customLabels:
- "auto-remediation"
systemLabels:
- "clusterName"
- "namespace"
```text
### GitLab
```bash
kubectl create secret generic gitlab-pat-token \
--from-literal=token=GITLAB_PAT_TOKEN \
--namespace=nirmata
kubectl apply -f - <<EOF
apiVersion: serviceagents.nirmata.io/v1alpha1
kind: ToolConfig
metadata:
name: toolconfig-sample
namespace: nirmata
spec:
type: gitlab
credentials:
method: pat
pat:
secretRef:
name: gitlab-pat-token
namespace: nirmata
key: token
EOF
```text
### Pull Request Labels
ToolConfig supports two label types:
- **`customLabels`** — static labels always applied to every PR (e.g., `auto-remediation`, `security`)
- **`systemLabels`** — dynamic labels computed at runtime from remediation context:
| System Label | Value |
|---|---|
| `branch` | The Git branch being remediated |
| `clusterName` | The cluster where violations were found |
| `appName` | ArgoCD application name (Hub Mode only) |
| `namespace` | Kubernetes namespace containing violations |
---
## LLMConfig
LLMConfig specifies the AI provider used to generate remediation plans.
### Nirmata AI (Default)
The Helm chart creates this automatically. Authentication uses the Service Account token injected at deployment time — no additional secrets needed.
```yaml
apiVersion: serviceagents.nirmata.io/v1alpha1
kind: LLMConfig
metadata:
name: nirmata-agent-llm
namespace: nirmata
spec:
type: nirmataAI
nirmataAI:
model: "" # empty string uses the current default model
```text
### AWS Bedrock
For EKS clusters with Pod Identity Agent:
```yaml
apiVersion: serviceagents.nirmata.io/v1alpha1
kind: LLMConfig
metadata:
name: nirmata-agent-llm
namespace: nirmata
spec:
type: bedrock
bedrock:
model: MODEL_ARN_OR_INFERENCE_ARN
region: AWS_REGION
```text
<details>
<summary>Full AWS IAM setup</summary>
```bash
aws iam create-role \
--role-name remediator-agent-role \
--assume-role-policy-document '{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": { "Service": "pods.eks.amazonaws.com" },
"Action": ["sts:AssumeRole", "sts:TagSession"]
}]
}'
aws iam put-role-policy \
--role-name remediator-agent-role \
--policy-name BedrockInvokePolicy \
--policy-document '{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": ["bedrock:InvokeModel", "bedrock:InvokeModelWithResponseStream"],
"Resource": "arn:aws:bedrock:<REGION>:<ACCOUNT_ID>:application-inference-profile/<PROFILE>"
}]
}'
aws eks create-pod-identity-association \
--cluster-name <CLUSTER_NAME> \
--namespace nirmata \
--service-account nirmata-agent \
--role-arn arn:aws:iam::<ACCOUNT_ID>:role/remediator-agent-role
```text
</details>
### Azure OpenAI
```bash
kubectl create secret generic azure-openai-credentials \
--from-literal=api-key=AZURE_API_KEY \
-n nirmata
apiVersion: serviceagents.nirmata.io/v1alpha1
kind: LLMConfig
metadata:
name: nirmata-agent-llm
namespace: nirmata
spec:
type: azure-openai
azureOpenAI:
endpoint: https://YOUR_RESOURCE_NAME.openai.azure.com/
deploymentName: DEPLOYMENT_NAME
apiKeySecretRef:
name: azure-openai-credentials
key: api-key
namespace: nirmata
```yaml
---
## Remediator
The Remediator resource ties everything together: it defines the environment mode, which clusters or applications to target, the schedule, and what actions to take.
### Environment Modes
| Mode | Use Case |
|------|----------|
| `localCluster` | Scan the cluster where the agent is installed |
| `argoHub` | Use ArgoCD to manage violations across multiple clusters |
### ArgoCD Hub Mode (Multi-Cluster)
```yaml
apiVersion: serviceagents.nirmata.io/v1alpha1
kind: Remediator
metadata:
name: remediator-argo-hub
namespace: nirmata
spec:
environment:
type: argoHub
target:
argoHubTarget:
argoAppSelector:
allApps: true # or specify names / labelSelector
remediation:
triggers:
- schedule:
crontab: "0 */6 * * *"
llmConfigRef:
name: nirmata-agent-llm
namespace: nirmata
gitCredentials:
name: toolconfig-sample
namespace: nirmata
eventPolling:
enabled: true
intervalMinutes: 5
actions:
- type: CreatePR
toolRef:
name: toolconfig-sample
namespace: nirmata
Targeting specific clusters or apps:
target:
argoHubTarget:
clusterNames:
- production-cluster
- staging-cluster
argoAppSelector:
names:
- nginx-demo
- web-app
labelSelector:
matchLabels:
team: platform
environment: production
Local Cluster Mode
See the example in Getting Started.
VCS Target Mode (Direct Repository Scanning)
Scan Git repositories directly without requiring a running cluster:
spec:
environment:
type: localCluster
target:
vcs:
policies:
- name: pod-security-policy
repo: https://github.com/your-org/policies
path: kyverno/pod-security.yaml
ref: main
resources:
- name: web-app-deployment
repo: https://github.com/your-org/manifests
path: deployments/web-app.yaml
ref: main
policyRefs:
- pod-security-policy
remediation:
triggers:
- schedule:
crontab: "0 */6 * * *"
llmConfigRef:
name: nirmata-agent-llm
namespace: nirmata
actions:
- type: CreatePR
toolRef:
name: toolconfig-sample
namespace: nirmata
Confidence-Based Actions
Control when automated PRs are created based on the AI’s confidence in its fix:
remediation:
actions:
- type: CreatePR
confidence:
- high # only create PRs when AI is highly confident
toolRef:
name: toolconfig-sample
namespace: nirmata
| Confidence | Meaning |
|---|---|
high | Nirmata AI is highly confident the fix is correct and safe |
low | A potential fix was found but human review is recommended |
Filtering by Severity
remediation:
filters:
policySelector:
matchSeverity:
- high
- critical
```yaml
---
## Split PR
The Split PR feature lets you split a pull request containing fixes for multiple policies into separate PRs — useful when different policies need different reviewers or approval workflows.
### How to Split
Add a comment to the PR mentioning `@nirmatabot`:
```text
@nirmatabot split-pr require-run-as-non-root disallow-privileged-containers
- One or more policy names (space-separated) after
split-pr - Use the exact policy names as they appear in the PR
What Happens
- Original PR — updated to contain only the remaining policies; a comment is added with a link to the new PR
- New PR — created on a new branch (prefixed
splitpr-) with only the specified policies; links back to the original PR - Both PRs are tracked independently by the agent