1. Checklist Summary
Use this checklist to track your hardening progress. Each area links to the detailed section below.2. TLS / HTTPS Everywhere
All traffic to and within the KaireonAI platform must be encrypted in transit.2.1 Ingress TLS Termination
Use an AWS ALB or nginx-ingress controller with TLS certificates managed by cert-manager. nginx-ingress with cert-manager:2.2 Internal Service TLS
For service-to-service communication within the cluster, consider a service mesh (Istio or Linkerd) for automatic mTLS. At minimum, ensure no sensitive data traverses unencrypted paths.3. Security Headers
Configure the following HTTP security headers on all responses. These can be set at the ingress level or in the Next.js application middleware.3.1 Ingress-Level Configuration (nginx)
3.2 Content Security Policy
Apply CSP to prevent XSS and data injection attacks. Adjustscript-src and style-src directives based on your CDN and third-party integrations.
unsafe-inline and unsafe-eval in script-src are necessary for Next.js in production. Use nonce-based CSP if your deployment supports it.
3.3 Header Reference
| Header | Value | Purpose |
|---|---|---|
| Strict-Transport-Security | max-age=63072000; includeSubDomains; preload | Enforce HTTPS for 2 years |
| X-Frame-Options | DENY | Prevent clickjacking |
| X-Content-Type-Options | nosniff | Prevent MIME-type sniffing |
| X-XSS-Protection | 0 | Disable legacy XSS filter (use CSP) |
| Referrer-Policy | strict-origin-when-cross-origin | Limit referrer information leakage |
| Permissions-Policy | camera=(), microphone=(), geolocation=() | Disable unnecessary browser features |
| Content-Security-Policy | (see above) | Prevent XSS and injection attacks |
4. Rate Limiting
Protect API endpoints from abuse and denial-of-service attacks.4.1 nginx-ingress Rate Limiting
4.2 Per-Endpoint Rate Limits
For granular control, implement rate limiting in the application layer using the Redis-backed rate limiter.| Endpoint Pattern | Rate Limit | Window | Notes |
|---|---|---|---|
/api/v1/decisions | 100 req/sec | Per IP | Decision scoring |
/api/v1/auth/* | 10 req/min | Per IP | Authentication endpoints |
/api/v1/connectors | 30 req/min | Per user | Connector CRUD |
/api/v1/pipelines/*/run | 5 req/min | Per user | Pipeline execution |
All other /api/v1/* | 60 req/min | Per user | General API |
4.3 Response Headers
Include rate limit information in responses to help clients self-regulate:5. Secret Management
5.1 AWS Secrets Manager + External Secrets Operator (ESO)
Never store secrets in Kubernetes manifests, Helm values, or environment variable files in source control. ExternalSecret resource:5.2 Secret Rotation Policy
| Secret | Rotation Frequency | Method |
|---|---|---|
| DATABASE_URL (password) | 90 days | Secrets Manager automatic rotation |
| NEXTAUTH_SECRET | 180 days | Manual rotation with rolling deploy |
| JWT_SIGNING_SECRET | 180 days | Dual-key validation during rotation |
| CONNECTOR_ENCRYPTION_KEY | 365 days | Re-encrypt connectors during rotation |
| TLS certificates | 60 days | cert-manager auto-renewal |
5.3 Rotation Procedure
- Create the new secret value in AWS Secrets Manager.
- Update the ESO
ExternalSecretif the remote ref path changed. - Wait for ESO to sync (up to
refreshInterval), or force sync:kubectl annotate externalsecret kaireon-secrets force-sync=$(date +%s) --overwrite. - Perform a rolling restart:
kubectl rollout restart deployment/kaireon-app -n kaireon. - Verify application health after restart.
- Remove the old secret version from Secrets Manager after confirming stability.
6. Network Policies
Restrict pod-to-pod communication to only what is necessary.6.1 Default Deny All
6.2 Allow Application Traffic
7. Pod Security Standards
Apply Kubernetes Pod Security Standards to prevent privilege escalation.7.1 Namespace Label (Restricted)
7.2 Pod Security Context
8. Database SSL
8.1 RDS SSL Configuration
Ensure all database connections use SSL by appendingsslmode=require (or sslmode=verify-full) to the connection string.
8.2 Certificate Bundle
Download the RDS CA certificate bundle and mount it into application pods:8.3 In-Cluster PostgreSQL
For the Startup tier running in-cluster PostgreSQL, enable SSL in the Helm values:9. Audit Log Retention
9.1 Application Audit Logs
KaireonAI emits structured audit log entries for all state-changing API operations. These logs include:- Timestamp (ISO 8601)
- User identity (user ID, email, IP address)
- Action performed (CREATE, UPDATE, DELETE)
- Resource type and identifier
- Request body hash (not the body itself, for sensitive data protection)
- Response status code
9.2 Retention Policy
| Log Type | Retention Period | Storage |
|---|---|---|
| Application audit logs | 1 year | CloudWatch Logs / S3 lifecycle |
| API access logs | 90 days | CloudWatch Logs |
| Database query logs | 30 days | RDS CloudWatch integration |
| Kubernetes audit logs | 90 days | CloudWatch Logs |
| Security event logs | 2 years | S3 Glacier after 90 days |
9.3 Log Forwarding
Use Fluent Bit as a DaemonSet to ship logs from pods to CloudWatch Logs or an external SIEM:9.4 Tamper Protection
- Enable CloudWatch Logs log group data protection for PII detection.
- Use S3 Object Lock (compliance mode) for long-term audit log archives.
- Enable CloudTrail for AWS API audit trail.
10. RBAC and Least-Privilege Access
10.1 Kubernetes RBAC
Create dedicated ServiceAccounts for each component. Do not use thedefault ServiceAccount.
10.2 IAM Roles for Service Accounts (IRSA)
Map Kubernetes ServiceAccounts to IAM roles with minimal permissions:| ServiceAccount | IAM Role | Permissions |
|---|---|---|
| kaireon-app | kaireon-app-role | Secrets Manager read, S3 read/write (uploads) |
| kaireon-worker | kaireon-worker-role | S3 read/write, SQS send/receive |
| external-secrets | kaireon-eso-role | Secrets Manager read |
10.3 Database Access Control
- Create separate database roles for the application and workers with the minimum required privileges.
- The application role should have SELECT, INSERT, UPDATE, DELETE on application tables.
- The worker role should have SELECT, INSERT, UPDATE on pipeline-related tables only.
- No role should have DROP, CREATE, or ALTER privileges in production. Schema migrations run as a separate CI/CD step with a privileged role.
11. Additional Hardening
11.1 Dependency Scanning
- Run
npm auditin CI pipelines. Fail builds on critical or high severity vulnerabilities. - Use Snyk or Trivy for container image scanning before pushing to ECR.
- Enable Amazon ECR image scanning on push.
11.2 Image Provenance
- Use specific image tags, never
latest. - Sign container images with cosign and verify signatures in admission controllers.
- Pull images only from trusted registries (ECR, Docker Hub official images).
11.3 Runtime Protection
- Deploy Falco for runtime anomaly detection (unexpected process execution, file access).
- Enable AWS GuardDuty for EKS runtime threat detection.
- Set
readOnlyRootFilesystem: trueon all containers (writable paths via emptyDir mounts).
12. API Key Authentication
KaireonAI supports API key authentication as an alternative to JWT Bearer tokens.How It Works
- API keys are passed via the
X-API-Keyheader - Keys are stored as SHA-256 hashes in the
ApiKeydatabase table (never in plaintext) - Each key has:
name,hashedKey,prefix(first 8 chars for identification),tenantId,role,expiresAt,revokedAt - Keys use the
krn_prefix for easy identification in logs
Production Checklist
- Rotate API keys every 90 days
- Set
expiresAton all keys — never issue non-expiring keys in production - Monitor
kaireon_http_request_duration_secondsfiltered by API key usage patterns - Revoke keys immediately when team members leave (set
revokedAt) - Use separate keys per integration (never share keys across services)
Key Management API
13. Connector Credential Encryption
All connector authentication configurations (authConfig field) are encrypted at rest using AES-256-GCM.
Configuration
Set theCONNECTOR_ENCRYPTION_KEY environment variable to a 32-byte hex string:
How It Works
- On
POST /api/v1/connectorsandPUT /api/v1/connectors/:id, theauthConfigJSON is encrypted before storage - On
GET /api/v1/connectors, credentials are decrypted for display (masked in list view, full in detail for admins) - Each encrypted value includes a random 12-byte IV and 16-byte auth tag
- If
CONNECTOR_ENCRYPTION_KEYis not set, credentials are stored in plaintext (development only)
Production Checklist
- Set
CONNECTOR_ENCRYPTION_KEYin all environments - Store the key in AWS Secrets Manager (see Section 5)
- Rotate the key annually — re-encrypt all connectors after rotation
- Never log or expose the encryption key in application logs