USMAN’S INSIGHTS
AI ARCHITECT
  • Home
  • About
  • Thought Leadership
  • Book
Press / Contact
USMAN’S INSIGHTS
AI ARCHITECT
⌘F
HomeBook
HomeBookThe Final Fortress: Capstone Secure Task API
Previous Chapter
Compliance Fundamentals SOC2 and HIPAA Awareness
Next Chapter
Assessment Production Security Compliance
AI NOTICE: This is the table of contents for the SPECIFIC CHAPTER only. It is NOT the global sidebar. For all chapters, look at the main navigation.

On this page

51 sections

Progress0%
1 / 51

Muhammad Usman Akbar Entity Profile

Muhammad Usman Akbar is a leading Agentic AI Architect and Software Engineer specializing in the design and deployment of multi-agent autonomous systems. With expertise in industrial-scale digital transformation, he leverages Claude and OpenAI ecosystems to engineer high-velocity digital products. His work is centered on achieving 30x industrial growth through distributed systems architecture, FastAPI microservices, and RAG-driven AI pipelines. Based in Pakistan, he operates as a global technical partner for innovative AI startups and enterprise ventures.

USMAN’S INSIGHTS
AI ARCHITECT

Transforming businesses into autonomous AI ecosystems. Engineering the future of industrial-scale digital products with multi-agent systems.

30X Growth
AI-First
Innovation

Navigation

  • Home
  • Book
  • About
  • Contact
Let's Collaborate

Have a Project in Mind?

Let's build something extraordinary together. Transform your vision into autonomous AI reality.

Start Your Transformation

© 2026 Muhammad Usman Akbar. All rights reserved.

Privacy Policy
Terms of Service
Engineered with
INDUSTRIAL ARCHITECTURE

Capstone: Secure Task API

You've spent this chapter building security knowledge piece by piece: the 4C model in Lesson 1, RBAC in Lesson 2, NetworkPolicies in Lesson 3, secrets in Lesson 4, PSS in Lesson 5, image scanning in Lesson 6, Dapr security in Lesson 7, and compliance mapping in Lesson 8. Now you apply everything together.

In December 2023, a startup lost their Series A funding when a security audit discovered their "production-ready" Kubernetes deployment was running pods as root, had no network segmentation, and stored database credentials in environment variables visible to any cluster user. The technical fix took two days. The reputation damage took six months to repair.

This capstone produces a Task API deployment that would pass that audit. You'll write a security specification first, compose all security controls into a unified deployment, execute a 10-point audit, run penetration test scenarios to verify controls work, and document your security posture for compliance evidence.


Security Specification (Write This First)

Before implementing anything, define what "secure" means for your Task API. This specification becomes your acceptance criteria.

Task API Security Specification

Application: Task API (FastAPI + SQLModel) Target Environment: Production Kubernetes namespace Compliance Context: SOC2 Type II preparation

Security Controls Required

#ControlSuccess CriteriaVerification Method
1Dedicated ServiceAccountPods run as task-api-sa, not defaultkubectl get pod -o jsonpath='{.spec.serviceAccountName}'
2Minimal RBAC permissionsSA can only get/list ConfigMaps in own namespacekubectl auth can-i returns no for secrets, other namespaces
3Default-deny NetworkPolicyAll ingress/egress blocked except explicit allowlistsTest pod cannot reach Task API without matching labels
4DNS egress allowedPods can resolve Kubernetes servicesnslookup kubernetes.default succeeds from pod
5Secrets via volume mountNo secrets in env vars, mounted at /secrets/kubectl get pod -o yaml shows no env.valueFrom.secretKeyRef
6PSS Restricted complianceNamespace enforces Restricted profilekubectl apply --dry-run=server accepts deployment
7No CRITICAL vulnerabilitiesTrivy scan passes with --severity CRITICALExit code 0 from scanner gate
8Dapr mTLS enabledSentry running, certificates validdapr status -k shows healthy Sentry
9Component scopes configuredStatestore only accessible by task-apiOther app-ids receive ERR_STATE_STORE_NOT_FOUND
10Audit logging enabledDapr API logging captures all requestsdapr.io/enable-api-logging: "true" annotation present

Non-Goals (explicitly excluded):

  • TLS termination at ingress (handled by Gateway API)
  • JWT authentication (handled by SecurityPolicy)
  • Multi-cluster federation (Advanced chapter)

Compose All Security Components

Apply the security components you've built throughout this chapter. Each file references patterns from its source lesson.

Step 1: Namespace with PSS Labels (L05)

Create 01-namespace.yaml:

yaml
apiVersion: v1 kind: Namespace metadata: name: task-api labels: pod-security.kubernetes.io/enforce: restricted pod-security.kubernetes.io/enforce-version: latest pod-security.kubernetes.io/audit: restricted pod-security.kubernetes.io/audit-version: latest pod-security.kubernetes.io/warn: restricted pod-security.kubernetes.io/warn-version: latest

Step 2: RBAC (L02)

Create 02-rbac.yaml:

yaml
--- apiVersion: v1 kind: ServiceAccount metadata: name: task-api-sa namespace: task-api automountServiceAccountToken: false --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: task-api-role namespace: task-api rules: - apiGroups: [""] resources: ["configmaps"] verbs: ["get", "list"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: task-api-binding namespace: task-api subjects: - kind: ServiceAccount name: task-api-sa namespace: task-api roleRef: kind: Role name: task-api-role apiGroup: rbac.authorization.k8s.io

Step 3: NetworkPolicy (L03)

Create 03-network-policy.yaml:

yaml
--- # Default deny all traffic apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default-deny-all namespace: task-api spec: podSelector: {} policyTypes: - Ingress - Egress --- # Allow DNS egress for service discovery apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-dns-egress namespace: task-api spec: podSelector: {} policyTypes: - Egress egress: - to: - namespaceSelector: matchLabels: kubernetes.io/metadata.name: kube-system ports: - protocol: UDP port: 53 --- # Allow ingress from gateway apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-gateway-ingress namespace: task-api spec: podSelector: matchLabels: app: task-api policyTypes: - Ingress ingress: - from: - namespaceSelector: matchLabels: kubernetes.io/metadata.name: envoy-gateway-system ports: - protocol: TCP port: 8000 --- # Allow egress to Redis statestore apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-redis-egress namespace: task-api spec: podSelector: matchLabels: app: task-api policyTypes: - Egress egress: - to: - podSelector: matchLabels: app: redis ports: - protocol: TCP port: 6379 --- # Allow egress to Dapr sidecar (localhost) apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-dapr-sidecar namespace: task-api spec: podSelector: matchLabels: app: task-api policyTypes: - Egress egress: - to: - podSelector: matchLabels: app: task-api ports: - protocol: TCP port: 3500 - protocol: TCP port: 50001

Step 4: Secrets Management (L04)

Create 04-secrets.yaml:

yaml
apiVersion: v1 kind: Secret metadata: name: task-api-secrets namespace: task-api type: Opaque data: database-url: cG9zdGdyZXNxbDovL3VzZXI6cGFzc0BkYi90YXNrcw== # base64 encoded redis-password: cmVkaXMtc2VjcmV0LXBhc3N3b3Jk # base64 encoded

Step 5: Dapr Components with Scopes (L07)

Create 05-dapr-components.yaml:

yaml
--- apiVersion: dapr.io/v1alpha1 kind: Component metadata: name: statestore namespace: task-api spec: type: state.redis version: v1 metadata: - name: redisHost value: redis:6379 - name: redisPassword secretKeyRef: name: task-api-secrets key: redis-password scopes: - task-api # Only task-api can access this component

Step 6: Task API Deployment (All Layers)

Create 06-deployment.yaml:

yaml
apiVersion: apps/v1 kind: Deployment metadata: name: task-api namespace: task-api spec: replicas: 3 selector: matchLabels: app: task-api template: metadata: labels: app: task-api annotations: # Dapr sidecar configuration dapr.io/enabled: "true" dapr.io/app-id: "task-api" dapr.io/app-port: "8000" # Security hardening (L07) dapr.io/sidecar-listen-addresses: "127.0.0.1" dapr.io/enable-api-logging: "true" spec: serviceAccountName: task-api-sa automountServiceAccountToken: false # Pod-level security context (L05) securityContext: runAsNonRoot: true runAsUser: 1000 runAsGroup: 1000 fsGroup: 1000 seccompProfile: type: RuntimeDefault containers: - name: task-api image: ghcr.io/org/task-api:v1.0.0@sha256:abc123... # Digest pinned (L06) ports: - containerPort: 8000 # Container-level security context (L05) securityContext: allowPrivilegeEscalation: false readOnlyRootFilesystem: true capabilities: drop: - ALL resources: limits: memory: "256Mi" cpu: "500m" requests: memory: "128Mi" cpu: "100m" # Secrets via volume mount, not env vars (L04) volumeMounts: - name: secrets mountPath: /secrets readOnly: true - name: tmp mountPath: /tmp volumes: - name: secrets secret: secretName: task-api-secrets - name: tmp emptyDir: {}

Apply All Components

bash
kubectl apply -f 01-namespace.yaml kubectl apply -f 02-rbac.yaml kubectl apply -f 03-network-policy.yaml kubectl apply -f 04-secrets.yaml kubectl apply -f 05-dapr-components.yaml kubectl apply -f 06-deployment.yaml

Output:

ResourceStatus
namespace/task-apicreated
serviceaccount/task-api-sacreated
role.rbac.authorization.k8s.io/task-api-rolecreated
rolebinding.rbac.authorization.k8s.io/task-api-bindingcreated
networkpolicy.networking.k8s.io/default-deny-allcreated
networkpolicy.networking.k8s.io/allow-dns-egresscreated
networkpolicy.networking.k8s.io/allow-gateway-ingresscreated
networkpolicy.networking.k8s.io/allow-redis-egresscreated
networkpolicy.networking.k8s.io/allow-dapr-sidecarcreated
secret/task-api-secretscreated
component.dapr.io/statestorecreated
deployment.apps/task-apicreated

10-Point Security Audit

Execute each audit check with its verification command. All items must pass before declaring the deployment production-ready.

Audit Check 1: Dedicated ServiceAccount

Command:

bash
kubectl get pods -n task-api -l app=task-api -o jsonpath='{.items[0].spec.service Account Name}'

Expected Output: task-api-sa

Pass Criteria: Output is task-api-sa, not default.

Audit Check 2: Minimal RBAC Permissions

Allowed operation:

bash
kubectl auth can-i get configmaps \ --as=system:serviceaccount:task-api:task-api-sa \ -n task-api

Expected Output: yes

Denied operations:

bash
kubectl auth can-i get secrets \ --as=system:serviceaccount:task-api:task-api-sa \ -n task-api kubectl auth can-i get configmaps \ --as=system:serviceaccount:task-api:task-api-sa \ -n default

Expected Output: no

Pass Criteria: ConfigMaps allowed in own namespace, secrets denied, other namespaces denied.

Audit Check 3: Default-Deny NetworkPolicy

Command:

bash
kubectl get networkpolicy -n task-api default-deny-all -o jsonpath='{.spec.policy Types}'

Expected Output: ["Ingress","Egress"]

Pass Criteria: Both Ingress and Egress policy types present with empty selectors (default deny).

Audit Check 4: DNS Egress Allowed

Command (run from within a Task API pod):

bash
kubectl exec -n task-api deploy/task-api -c task-api -- nslookup kubernetes.default

Expected Output:

text
Server: 10.96.0.10 Address: 10.96.0.10#53 Name: kubernetes.default.svc.cluster.local Address: 10.96.0.1

Pass Criteria: DNS resolution succeeds despite default-deny egress.

Audit Check 5: Secrets via Volume Mount

Detection command:

bash
kubectl get pods -n task-api -l app=task-api -o yaml | grep -A5 "env:" | grep secret Key Ref || echo "No secret Key Ref in env vars"

Expected Output: No secretKeyRef in env vars

Verify volume mount exists:

bash
kubectl get pods -n task-api -l app=task-api -o jsonpath='{.items[0].spec.containers[0].volume Mounts[?(@.name=="secrets")].mount Path}'

Expected Output: /secrets

Pass Criteria: No secretKeyRef in environment variables, secrets mounted at /secrets.

Audit Check 6: PSS Restricted Compliance

Command:

bash
kubectl apply -f 06-deployment.yaml --dry-run=server

Expected Output: deployment.apps/task-api created (server dry run)

Pass Criteria: No PSS violations reported, deployment accepted (restricted labels active).

Audit Check 7: No CRITICAL Vulnerabilities

Command:

bash
trivy image ghcr.io/org/task-api:v1.0.0 --severity CRITICAL --exit-code 1

Expected Output:

text
ghcr.io/org/task-api:v1.0.0 (debian 12.5) ========================================= Total: 0 (CRITICAL: 0)

Pass Criteria: Exit code 0, zero CRITICAL vulnerabilities.

Audit Check 8: Dapr mTLS Enabled

Command:

bash
dapr status -k | grep dapr-sentry

Expected Output: dapr-sentry dapr-system True Running...

Verify certificate validity:

bash
kubectl get pods -n dapr-system -l app=dapr-sentry -o name | head -1 | \ xargs -I {} kubectl exec {} -n dapr-system -- \ openssl x509 -in /var/run/secrets/dapr.io/tls/ca.crt -noout -enddate

Expected Output: notAfter=Jan 15 10:23:45 2025 GMT

Pass Criteria: Sentry healthy, certificates not expired.

Audit Check 9: Component Scopes Configured

Command (from a pod with different app-id):

bash
# Create test pod with different app-id kubectl run test-attacker -n task-api --image=curlimages/curl:latest \ --annotations="dapr.io/enabled=true,dapr.io/app-id=attacker" \ --command -- sleep 3600 # Attempt to access statestore kubectl exec -n task-api test-attacker -c daprd -- \ curl -s http://localhost:3500/v1.0/state/statestore # Cleanup kubectl delete pod test-attacker -n task-api

Expected Output: {"errorCode": "ERR_STATE_STORE_NOT_FOUND", ...}

Pass Criteria: Non-scoped app-ids cannot see the statestore.

Audit Check 10: Audit Logging Enabled

Command:

bash
kubectl get pods -n task-api -l app=task-api -o jsonpath='{.items[0].metadata.annotations.dapr\.io/enable-api-logging}'

Expected Output: true

Pass Criteria: Annotation present and set to "true".


Audit Summary Script

Combine all checks into an executable audit script secure-task-api-audit.sh:

bash
#!/bin/bash # secure-task-api-audit.sh echo "=== Task API Security Audit ===" echo "" PASS=0 FAIL=0 # Check 1: Dedicated ServiceAccount SA=$(kubectl get pods -n task-api -l app=task-api -o jsonpath='{.items[0].spec.serviceAccountName}' 2>/dev/null) if [ "$SA" = "task-api-sa" ]; then echo "[PASS] 1. Dedicated ServiceAccount: $SA" ((PASS++)) else echo "[FAIL] 1. Dedicated ServiceAccount: got '$SA', expected 'task-api-sa'" ((FAIL++)) fi # Check 2: Minimal RBAC (test denied operation) SECRETS=$(kubectl auth can-i get secrets --as=system:serviceaccount:task-api:task-api-sa -n task-api 2>/dev/null) if [ "$SECRETS" = "no" ]; then echo "[PASS] 2. Minimal RBAC: secrets access denied" ((PASS++)) else echo "[FAIL] 2. Minimal RBAC: secrets access should be denied" ((FAIL++)) fi # Check 3: Default-deny NetworkPolicy NP=$(kubectl get networkpolicy -n task-api default-deny-all -o jsonpath='{.spec.policyTypes}' 2>/dev/null) if [[ "$NP" == *"Ingress"* ]] && [[ "$NP" == *"Egress"* ]]; then echo "[PASS] 3. Default-deny NetworkPolicy: both Ingress and Egress" ((PASS++)) else echo "[FAIL] 3. Default-deny NetworkPolicy: missing policy types" ((FAIL++)) fi # Check 10: Audit logging enabled LOGGING=$(kubectl get pods -n task-api -l app=task-api -o jsonpath='{.items[0].metadata.annotations.dapr\.io/enable-api-logging}' 2>/dev/null) if [ "$LOGGING" = "true" ]; then echo "[PASS] 10. Audit logging: enabled" ((PASS++)) else echo "[FAIL] 10. Audit logging: not enabled" ((FAIL++)) fi echo "" echo "=== Audit Results ===" echo "PASSED: $PASS / 4 Automated Checks" echo "NOTE: Perform manual verification for checks 4, 5, 7, 8, 9."

Penetration Test Scenarios

Security controls are only valuable if they actually prevent attacks. These scenarios verify your controls work against realistic attack vectors.

Scenario 1: RBAC Bypass Attempt

Attack: Compromised pod attempts to read secrets across namespaces.

Setup/Execution:

bash
# Deploy attacker pod kubectl run attacker -n task-api --image=bitnami/kubectl:latest \ --serviceaccount=task-api-sa \ --command -- sleep 3600 # Execution kubectl exec -n task-api attacker -- kubectl get secrets -n task-api kubectl exec -n task-api attacker -- kubectl get pods -n kube-system # Cleanup kubectl delete pod attacker -n task-api

Expected Result: Error from server (Forbidden): ... cannot list resource ...

Scenario 2: Network Escape Attempt

Attack: Compromised pod attempts to reach services outside allowed NetworkPolicies.

Setup/Execution:

bash
# Deploy attacker pod kubectl run network-attacker -n task-api --image=curlimages/curl:latest \ --command -- sleep 3600 # Execution kubectl exec -n task-api network-attacker -- curl -s --max-time 5 https://google.com kubectl exec -n task-api network-attacker -- curl -s --max-time 5 http://kubernetes-dashboard.svc # Cleanup kubectl delete pod network-attacker -n task-api

Expected Result: curl: (28) Connection timed out...

Scenario 3: Privilege Escalation Attempt

Attack: Pod attempts to run privileged container or escape PSS restrictions.

yaml
# privileged-attacker.yaml apiVersion: v1 kind: Pod metadata: name: priv-attacker namespace: task-api spec: containers: - name: attacker image: nginx:latest securityContext: privileged: true

Execution: kubectl apply -f privileged-attacker.yaml

Expected Result: Error from server (Forbidden): ... violates PodSecurity "restricted:latest"...


Security Posture Documentation

Create documentation for compliance auditors. This template maps your controls to common compliance frameworks.

Security Posture Document Template

Control CategoryControlImplementationEvidence Location
IdentityDedicated ServiceAccounttask-api-sa with automount disabled02-rbac.yaml
AuthorizationRBAC least privilegeConfigMap read-only02-rbac.yaml, audit check 2
NetworkDefault-deny NetworkPolicyEgress/Ingress blocked03-network-policy.yaml
SecretsVolume-mounted secretsNo env var exposure04-secrets.yaml, 06-deployment.yaml
ContainerPSS Restricted profilerunAsNonRoot, drop ALL caps01-namespace.yaml, 06-deployment.yaml
Supply ChainImage scanningTrivy CRITICAL gateCI/CD workflow
IsolationComponent scopesStatestore restricted to task-api05-dapr-components.yaml
AuditAPI loggingDapr request logging06-deployment.yaml annotation

Try With AI

Test your ability to design, implement, and audit production security configurations.

Prompt 1:

bash
Write a security specification for a payment-processing microservice that: - Handles PCI-DSS data - Needs database connectivity - Uses Dapr for state management - Runs in a shared Kubernetes cluster Define the 10-point audit checklist with specific success criteria.

What you're learning: Security specification design requires understanding threat models before implementation. PCI-DSS adds requirements beyond standard production security: encrypted data at rest, stricter network segmentation, key rotation policies. Notice how your specification changes when compliance requirements increase.

Prompt 2:

bash
My Task API passed 9/10 audit checks, but check 7 (Trivy scan) found 3 HIGH vulnerabilities in the Python base image. The vulnerabilities are in packages my application doesn't directly use. Should I: A) Switch to Alpine/Distroless base image B) Accept the risk and document it C) Wait for upstream fixes D) Something else? Walk me through the decision framework.

What you're learning: Security is about risk management, not zero vulnerabilities. The decision depends on: Is the vulnerable code reachable? Is there a known exploit? What's the remediation timeline? Distroless images reduce attack surface but may break your application. This requires analyzing tradeoffs, not following rules.

Prompt 3:

bash
Design a penetration test scenario that validates Dapr component scopes are working correctly. The scenario should: - Create an "attacker" workload in the same namespace - Attempt to access multiple Dapr components - Produce clear pass/fail evidence - Be safe to run in a shared environment

What you're learning: Penetration testing validates that security controls actually work. The key insight is that scopes are enforced by app-id, so your test needs a pod with a different Dapr app-id annotation. The test should be non-destructive (read attempts, not writes) and cleanup after itself.

Security Reminder

A 10-point audit provides evidence that controls are configured correctly at a point in time. Production security requires continuous monitoring: alert on RBAC changes, track NetworkPolicy modifications, scan images on schedule. This capstone establishes your security baseline; operational practices maintain it.