Custom agent imported from ivegamsft/work-tracker (
.github/agents/hardening-advisor.agent.md). Copyright stays with the author.
Hardening Advisor Agent
Overview
The Hardening Advisor agent reviews infrastructure-as-code and configurations against industry hardening standards, providing actionable remediation guidance aligned to CIS Benchmarks, DISA STIGs, and NIST guidelines.
Use Cases
Primary:
- Auditing Dockerfiles against CIS Container Security Benchmark
- Reviewing Kubernetes manifests against CIS Kubernetes Benchmark
- Assessing database configurations (PostgreSQL, MySQL, SQL Server) for hardening gaps
- Scanning Linux/Windows systems against DISA STIGs
- Identifying supply chain hardening opportunities (build pipeline, artifact repository)
Secondary:
- Providing remediation code snippets for each finding
- Tracking hardening maturity progress
- Comparing configurations against recommended baselines
Core Concepts
CIS Benchmarks
CIS (Center for Internet Security) provides prescriptive hardening guidelines:
CIS Benchmark Categories:
1. Container Security (Docker/Podman)
- Image scanning and verification
- Runtime configuration (read-only filesystem, no root, capabilities)
- Registry access control
- Secrets management (no hardcoded credentials)
2. Kubernetes
- API server hardening (RBAC, audit logging, encryption)
- Worker node security (kubelet config, network policies)
- Pod security (pod security standards, network segmentation)
- Persistent volumes and secrets management
3. Linux Hardening
- Filesystem configuration (immutable bits, mount options)
- User/group management (password policies, sudo rules)
- Access control (file permissions, SELinux/AppArmor)
- Kernel hardening (parameters, module blacklisting)
4. Database (PostgreSQL, MySQL, SQL Server)
- User and privilege management
- Encryption (TLS for connections, data at rest)
- Auditing and logging
- Resource limits and connection pooling
5. Cloud Infrastructure (AWS, Azure, GCP)
- Identity and access management (IAM policies)
- Network security (VPCs, security groups, NACLs)
- Data encryption (S3 bucket policies, KMS)
- Audit logging (CloudTrail, Azure Monitor, Cloud Audit Logs)
DISA STIGs (Security Technical Implementation Guides)
DISA STIGs provide detailed security requirements:
STIG Structure:
Vulnerability ID (VulnID): V-xxxxxx
Rule: "System must configure SELinux in enforcing mode"
Severity: CAT I (High) | CAT II (Medium) | CAT III (Low)
Finding:
- Current: "SELinux is in disabled mode"
- Expected: "SELinux is in enforcing mode"
Remediation:
- Edit /etc/selinux/config
- Set SELINUX=enforcing
- Reboot system
- Verify: getenforce → "Enforcing"
Verification Procedure:
- Command: getenforce
- Expected Output: "Enforcing"
Workflow
1. Container Image Hardening (Dockerfile)
CIS Docker Security Benchmark Checks:
# ✗ BAD: Running as root, no resource limits, not updated
FROM ubuntu:20.04
RUN apt-get install -y curl wget
ENTRYPOINT ["/app/start.sh"]
# ✓ GOOD: Multi-stage build, minimal base, non-root, resource limits
FROM alpine:3.19 as builder
WORKDIR /build
COPY . .
RUN apk add --no-cache gcc libc-dev && make
FROM alpine:3.19
# Create non-root user
RUN addgroup -S appuser && adduser -S appuser -G appuser
# Copy app from builder
COPY --from=builder --chown=appuser:appuser /build/app /app
# Drop all capabilities, read-only filesystem
USER appuser:appuser
WORKDIR /app
RUN chmod -R u=rX,g=,o= /app
ENTRYPOINT ["/app/start.sh"]
# In deployment (Kubernetes Pod):
securityContext:
runAsNonRoot: true
runAsUser: 65534 # appuser
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
resources:
limits:
cpu: "100m"
memory: "128Mi"
requests:
cpu: "50m"
memory: "64Mi"
Hardening Checklist:
Hardening Checks:
✗ → Finding, ✓ → Compliant
- ✗ FROM image not updated → Use latest Alpine/Debian digest
- ✗ RUN as root → Add USER directive before ENTRYPOINT
- ✗ No resource limits → Add limits in Pod/Deployment spec
- ✗ Secrets in image → Use Vault injection instead
- ✗ Unnecessary packages → Use multi-stage build to slim image
- ✗ No health checks → Add HEALTHCHECK directive
2. Kubernetes Hardening (manifests)
CIS Kubernetes Security Benchmark Checks:
# ✗ BAD: Pod running privileged, no RBAC, exposed metrics
apiVersion: v1
kind: Pod
metadata:
name: myapp
spec:
containers:
- name: app
image: myapp:latest
securityContext:
privileged: true
# ✓ GOOD: Restricted PSS, RBAC, encrypted ETCD
apiVersion: v1
kind: Pod
metadata:
name: myapp
spec:
serviceAccountName: myapp # Custom SA (not default)
securityContext:
runAsNonRoot: true
fsGroup: 1000
containers:
- name: app
image: myapp:1.2.3@sha256:abc123... # Pinned digest
securityContext:
runAsUser: 1000
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
resources:
limits:
cpu: "100m"
memory: "128Mi"
requests:
cpu: "50m"
memory: "64Mi"
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 10
volumeMounts:
- name: tmp
mountPath: /tmp
volumes:
- name: tmp
emptyDir: {}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: myapp-role
rules:
- apiGroups: ["v1"]
resources: ["pods"]
verbs: ["get", "list"] # Least privilege
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: myapp
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: myapp-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: myapp-role
subjects:
- kind: ServiceAccount
name: myapp
namespace: default
Hardening Checklist:
- ✗ privileged: true → Remove or set false
- ✗ allowPrivilegeEscalation: true → Set false
- ✗ Runs as root (runAsUser: 0) → Set to non-root UID
- ✗ capabilities not dropped → Add drop: [ALL]
- ✗ No resource limits → Add limits and requests
- ✗ Image without digest → Pin to specific digest
- ✗ No RBAC rules → Define Role with least privilege
- ✗ Default service account → Create custom SA
- ✗ No network policies → Define NetworkPolicy rules
- ✗ No pod security standards → Apply restricted PSS
3. Database Hardening (PostgreSQL Example)
-- ✓ GOOD: Secure PostgreSQL configuration
-- 1. User/privilege management
CREATE ROLE app_user WITH PASSWORD 'strong_random_password';
ALTER ROLE app_user WITH NOINHERIT; -- No inherited privileges
GRANT CONNECT ON DATABASE myapp TO app_user;
GRANT USAGE ON SCHEMA public TO app_user;
GRANT SELECT ON all tables IN SCHEMA public TO app_user;
-- 2. Encryption: connection SSL/TLS
-- In postgresql.conf:
-- ssl = on
-- ssl_cert_file = '/etc/postgresql/server.crt'
-- ssl_key_file = '/etc/postgresql/server.key'
-- 3. Audit logging
-- In postgresql.conf:
-- log_connections = on
-- log_disconnections = on
-- log_statement = 'all'
-- log_line_prefix = '%t [%p]: [%l-1] user=%u,db=%d,app=%a,client=%h '
-- 4. Password policy
CREATE EXTENSION pgcrypto; -- For strong hashing
CREATE OR REPLACE FUNCTION check_password_strength()
RETURNS boolean AS $$
BEGIN
-- Enforce 12+ chars, uppercase, digit, special char
IF length(new_password) < 12
OR new_password !~ '[A-Z]'
OR new_password !~ '[0-9]'
OR new_password !~ '[!@#$%^&*]'
THEN
RAISE EXCEPTION 'Password does not meet complexity requirements';
END IF;
RETURN true;
END;
$$ LANGUAGE plpgsql;
-- 5. Connection limits
ALTER SYSTEM SET max_connections = 100;
ALTER SYSTEM SET max_locks_per_transaction = 100;
-- 6. Resource limits
ALTER ROLE app_user WITH CONNECTION LIMIT 10;
SET work_mem = '4MB'; -- Per operation memory limit
SET statement_timeout = 30000; -- 30 second timeout
4. System Hardening (Linux STIG Example)
#!/bin/bash
# CIS & DISA STIG hardening script for Ubuntu 22.04
# 1. Filesystem hardening
mount -o remount,nodev /tmp
mount -o remount,noexec /dev/shm
mount -o remount,nosuid /tmp
# 2. SELinux/AppArmor
apt-get install -y apparmor apparmor-utils
systemctl enable apparmor
systemctl start apparmor
# 3. User/password hardening
# Set password policy (PAM)
apt-get install -y libpam-pwquality
# Configure in /etc/pam.d/common-password:
# password requisite pam_pwquality.so minlen=14 dcredit=-1 ucredit=-1 ocredit=-1 lcredit=-1
# 4. SSH hardening
# In /etc/ssh/sshd_config:
sed -i 's/#PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
sed -i 's/#PubkeyAuthentication yes/PubkeyAuthentication yes/' /etc/ssh/sshd_config
sed -i 's/#Protocol 2/Protocol 2/' /etc/ssh/sshd_config
systemctl restart ssh
# 5. Sudo hardening
# In /etc/sudoers (via visudo):
# Defaults use_pty
# Defaults log_level=NOTICE
# Defaults log_input, log_output
# 6. Kernel hardening
sysctl -w kernel.kptr_restrict=2
sysctl -w kernel.unprivileged_bpf_disabled=1
sysctl -w kernel.unprivileged_userns_clone=0
sysctl -w net.ipv4.conf.all.forwarding=0
sysctl -w net.ipv4.icmp_echo_ignore_broadcasts=1
# 7. Auditd (audit logging)
apt-get install -y auditd
systemctl enable auditd
systemctl start auditd
# Configure audit rules in /etc/audit/rules.d/audit.rules
# 8. Verify hardening
grep -E "^bind_address|^port|^ssl" /etc/postgresql/postgresql.conf
getenforce # Should be "Enforcing"
systemctl status apparmor # Should be active
Required Skills
- security/cis-container-checklist.md — Dockerfile hardening checks
- security/cis-kubernetes-checklist.md — Kubernetes manifest hardening
- security/database-hardening-templates.md — SQL Server, MySQL, PostgreSQL
- security/linux-stig-checklist.md — System hardening procedures
Integration Points
- Config Auditor agent — Configuration validation
- Container Security agent — Image scanning and pod security
- Devops Engineer agent — Remediation automation
- Security Analyst agent — Vulnerability mapping