Production-grade demonstration of Secretless Application Architecture on AWS using AWS Secrets Manager and HashiCorp Vault (self-hosted EC2 with KMS auto-unseal). Features IRSA (IAM Roles for Service Accounts), KMS Customer Managed Keys (CMK) with automatic rotation, VPC Interface Endpoints, and least-privilege IAM roles with explicit Deny rules — eliminating all hardcoded static credentials.
Note
Portfolio & Architecture Showcase: This repository is a technical demonstration designed to showcase enterprise AWS zero-trust architecture, IAM security boundaries, and infrastructure-as-code patterns. All secret strings, keys, and tokens in configuration files and scripts are synthetic sample placeholders.
graph TD
subgraph VPC["AWS Private VPC (No Public Internet Secrets Traffic)"]
subgraph PrivateSubnet["Private Subnet"]
App["Go App Container (Scratch Base, UID 10001)"]
Vault["Self-Hosted Vault EC2 (t3.small, KMS Auto-Unseal)"]
end
subgraph VPCEndpoints["VPC Interface Endpoints (Port 443)"]
VPCSM["Secrets Manager Endpoint"]
VPCKMS["KMS Endpoint"]
VPCSTS["STS Endpoint"]
end
end
subgraph IAM["AWS IAM & Zero-Trust Controls"]
OIDC["EKS OIDC Provider (IRSA)"]
KMSCMK["KMS Customer Managed Key (CMK)"]
CIRole["CI/CD Role (OIDC) - Explicit Deny Read"]
AuditorRole["Human Auditor - MFA Required + Deny Read"]
end
App -->|1. Short-Lived OIDC Token| OIDC
App -->|2. GetSecretValue via Private Endpoint| VPCSM
VPCSM -->|3. Decrypt Key| KMSCMK
Vault -->|KMS Auto-Unseal| VPCKMS
CIRole -.->|Can Put/Seed Secrets, Denied GetSecretValue| VPCSM
AuditorRole -.->|List/Describe Only with MFA, Denied GetSecretValue| VPCSM
- Dual Provider Interface: Abstracted Go
Providerinterface supporting both AWS Secrets Manager and HashiCorp Vault with in-memory TTL caching and circuit-breaker fallback. - Zero Static Credentials (IRSA & OIDC): Pods authenticate to AWS using short-lived EKS OIDC tokens. GitHub Actions uses OIDC federation — zero long-lived AWS secret keys stored in GitHub.
- Explicit IAM Deny Rules:
- App Role: Allowed
GetSecretValueon specific secret ARNs only; explicitlyDenyonDeleteSecretandPutSecretValue. - CI Role: Allowed
PutSecretValueandCreateSecret(seeding); explicitlyDenyonGetSecretValue(cannot exfiltrate secrets). - Auditor Role: Requires
aws:MultiFactorAuthPresent=true; explicitlyDenyonGetSecretValue.
- App Role: Allowed
- Network Security: Private AWS Interface VPC Endpoints (
secretsmanager,kms,ssm,sts). All traffic stays within private VPC CIDR. - KMS CMK Key Management: Customer Managed Keys with annual automatic key rotation enabled.
- Zero-Downtime Secret Rotation: Lambda-based database secret rotation with in-memory TTL cache stale-while-revalidate background refresh.
- Hardened App & Container: Multi-stage Docker build targeting
scratch, non-root user (UID 10001), read-only root filesystem, dropped Linux capabilities. - DevSecOps Pipeline: Integrated
trufflehogsecret scanning,gosecAST security analysis, andTrivycontainer CVE scanning in CI.
aws-secrets-zerotrust/
├── terraform/
│ ├── modules/
│ │ ├── vault/ # EC2 self-hosted Vault with KMS auto-unseal
│ │ ├── secrets-manager/ # AWS Secrets Manager secrets, KMS CMK, rotation
│ │ ├── iam/ # IRSA, CI OIDC, least privilege IAM roles with explicit Deny
│ │ └── networking/ # VPC, private subnets, VPC Endpoints
│ └── environments/
│ ├── dev/ # Short KMS deletion (7 days), rotation disabled
│ └── prod/ # KMS deletion (30 days), rotation enabled (30 days), MFA enforcement
├── app/
│ ├── cmd/server/main.go # Go 1.22 HTTP server with fail-fast secret validation
│ ├── internal/
│ │ ├── secrets/ # Provider interface, AWS & Vault SDK clients, TTL cache
│ │ ├── config/ # Environment configuration loader
│ │ └── handlers/ # /health, /ready, /demo, /metrics endpoints
│ └── Dockerfile # Multi-stage scratch build, non-root UID 10001
├── vault-config/
│ ├── policies/ # Least privilege Vault HCL policies (dev/prod/admin)
│ ├── auth/ # AWS IAM and AppRole auth configuration files
│ └── secrets/ # KV v2 setup & rotation scripts
├── k8s/ # IRSA ServiceAccount, deployment, service, Vault Agent sidecar
├── .github/workflows/ # CI (TruffleHog, Gosec, Trivy), Terraform plan/apply, rotation test
├── scripts/ # Bootstrap (S3/DynamoDB/KMS), Vault init, setup AWS auth, e2e demo
├── docs/ # Zero-trust model, secret rotation strategy, threat model
├── .gitignore
└── README.md
- AWS CLI v2 configured with Administrator credentials
- Terraform >= 1.5.0
- Go 1.22+
- kubectl & Docker
chmod +x scripts/*.sh vault-config/secrets/*.sh
./scripts/bootstrap.shcd terraform/environments/dev
terraform init
terraform plan
terraform apply -auto-approvecd terraform/environments/prod
terraform init
terraform plan
terraform apply -auto-approve# Obtain Vault private IP from terraform output
export VAULT_ADDR="http://<VAULT_PRIVATE_IP>:8200"
# Initialize Vault & save unseal keys to AWS Secrets Manager
./scripts/vault-init.sh dev
# Configure Vault AWS IAM Auth Method
./scripts/setup-aws-auth.sh dev
# Seed Vault KV v2 secrets
./vault-config/secrets/setup-kv.sh# Local execution
cd app
export APP_ENV=dev
export SECRET_PROVIDER=aws-secrets-manager
export AWS_REGION=us-east-1
export SECRET_PATH_PREFIX=myapp/dev/app
go run ./cmd/server/main.go
# Kubernetes Deployment
kubectl apply -f k8s/namespace.yaml
kubectl apply -f k8s/serviceaccount.yaml
kubectl apply -f k8s/deployment.yaml
kubectl apply -f k8s/service.yaml./scripts/demo.sh devMd. Iqbal Haider Khan
- Email: ihkokil@gmail.com
- LinkedIn: https://www.linkedin.com/in/ihkokil/
- GitHub: https://www.github.com/ihkokil/
This project is licensed under the MIT License - see the LICENSE file for details.