LANDING ZONE · AWS ORGANIZATION Management account billing · SCPs · no workloads OU · Security Log archive CloudTrail · Config · 365 d Audit GuardDuty · Security Hub OU · Workloads prod VPC · ECS · RDS staging same shape, smaller OU · Sandbox dev-* per engineer · budget alarms data-science no production data IAM Identity Center SSO · MFA · permission sets Just-in-time access approval in Teams · 2 h · break-glass Cost control budgets · anomaly alerts · tags SERVICE CONTROL POLICIES deny leaving the organization · deny disabling CloudTrail · deny regions outside eu-* · deny root user actions require encryption on S3 and EBS · require IMDSv2 · deny public S3 unless tagged public=true
IDENTITY · ZERO TRUST ON MICROSOFT ENTRA People staff, contractors Conditional Access MFA, device, location PIM just-in-time, 2 h Approval Teams · logged Microsoft 365 mail · files · DLP labels Azure subscriptions · RBAC SaaS apps SSO and SCIM POLICY SET # Policy Applies to Result CA-01 Require MFA for all users everyone enforced CA-02 Block legacy authentication everyone enforced CA-03 Compliant device for admins admin roles enforced CA-04 Sign-in risk high: block everyone enforced PIM-1 Global Admin: 0 standing, 2 h JIT admin roles enforced PIM-2 Break-glass: 2 accounts, alerts emergency monitored ACCESS REVIEW · quarterly owners confirm privileged access assignments reviewed 142 removed 19 converted to eligible 31 evidence: signed report, 4 pages
.github/workflows/deploy.yml name: deploy on: push: { branches: [main] } permissions: id-token: write contents: read jobs: plan: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ vars.DEPLOY_ROLE }} aws-region: eu-central-1 - run: terraform init -input=false - run: terraform plan -out=tfplan - run: terraform show -no-color tfplan|tee plan.txt apply: needs: plan environment: production # approval required steps: - run: terraform apply tfplan - run: ./scripts/smoke.sh - run: ./scripts/log-change.sh "$GITHUB_SHA" PIPELINE · every change, one path commit signed plan diff reviewed approve a human, logged apply with rollback smoke checks pass log change + rollback
DECISION PAPER · 04 Database engine for the rebuilt platform Question which managed engine carries the platform for the next five years Options A managed PostgreSQL, Multi-AZ B keep MySQL, managed C serverless Decided A, on the evidence below; not B, despite less adviser work Criterion A PostgreSQL B MySQL C Serverless Migration risk rehearsed twice none schema rewrite Cost, 3 yr known, fixed known, fixed variable Failover automatic, 60 s automatic, 60 s automatic Team skills 2 of 3 engineers 3 of 3 0 of 3 Reversibility high n/a low Due-diligence position - architecture diagram with data flows, current and target - security findings register with closure evidence - infrastructure as code, reviewed, owned by the company - runbooks: deploy, rollback, restore, incident REVIEW · read-only 171 files · 3 days · findings 23 critical 2 high 6 medium 9 low 6 decision brief: 4 pages
TARGET ARCHITECTURE · AWS · eu-central-1 VPC 10.20.0.0/16 public subnets · 2 AZ private subnets · 2 AZ ALB https :443 NAT egress only CloudFront WAF · TLS 1.2+ Route 53 apex, www ECS Fargate api · 2 tasks ECS Fargate worker RDS PostgreSQL Multi-AZ, encrypted, PITR 15 min ElastiCache sessions Secrets rotation 30 d S3 uploads · private · signed URLs CloudWatch · GuardDuty alerts to on-call infra/prod/ecs.tf resource "aws_ecs_service" "api"{ name = "api" cluster = local.cluster_id task_definition = ...api.arn desired_count = 2 launch_type = "FARGATE" network_configuration { subnets = module.vpc.subnets security_groups = [sg.api.id] assign_public_ip = false } deployment_circuit_breaker { enable = true rollback = true } } resource "aws_db_instance" "db" { engine = "postgres" multi_az = true storage_encrypted = true backup_retention_period = 14 deletion_protection = true }
INCIDENT · TIMELINE AND CONTAINMENT 09:14 alert: unusual sign-in, admin account, new country 09:19 session revoked; password and MFA reset; token invalidated 09:26 conditional access: block legacy auth, require admin MFA 09:41 mailbox rules reviewed: 1 forwarding rule removed 10:05 scope confirmed: one account, no data exported (audit log) 11:02 root cause: phished credential, no MFA on the account 11:30 client briefed in plain language: what happened, what changed day 2 PIM enabled: admin rights just-in-time, 2 h, approval in Teams day 3 tabletop with the team; runbook IR-1 updated WHAT CHANGED access · monitoring · training MFA enforced: 100 % of accounts admin standing access: 0 sign-in risk alerts: on-call phishing drill: quarterly log retention: 365 days REPORT · 4 pages non-technical first, evidence appendix
CONTROLS MATRIX · ISO 27001:2022 Annex A (extract) Control Policy In the systems Evidence Owner A.5.15 Access control yes Entra CA, RBAC policy export, review log IT A.5.17 Authentication yes MFA enforced, PIM sign-in logs, PIM report IT A.8.2 Privileged access yes JIT, 2 h, approval activation log Sec A.8.9 Configuration mgmt yes Terraform, reviewed PR history DevOps A.8.13 Backup yes 14 d PITR, drills restore drill 2025-11 DevOps A.8.15 Logging yes central, 365 d retention config Sec A.8.16 Monitoring yes alerts: on-call alert history Sec A.8.24 Cryptography yes KMS, TLS 1.2+ KMS policy, scan Sec A.8.28 Secure coding partial CI checks pipeline config Dev A.8.32 Change mgmt yes PR + change log log with rollback DevOps AUDIT READINESS controls 93 · implemented 89 · gaps 4 EVIDENCE INDEX E-01 access review Q3, signed E-02 PIM activation log, 90 days E-03 restore drill, screenshots and timings E-04 DNS transfer record, before and after E-05 documentation vs live product: 9 defects, fixed
AI IN THE BUSINESS · DATA FLOW AND RULES People staff, tools Gateway redact · log · allow-list Model provider no training on data Internal store same permissions RULES, IN ONE PAGE 1 Data leaves the tenant only if redacted. 2 Each allowed tool has an owner and data map. 3 Prompts and outputs are logged like any tool. 4 Internal store access follows existing rules. 5 Anything that acts needs a human approval. 6 Quarterly review of tools, costs, incidents. TOOL SELECTION · evidence, not demos Tool Residency Training opt-out Verdict Assistant A EU yes, contract allowed Assistant B US no blocked Code helper EU yes no secrets Meeting notes US yes pilot, 1 team
RUNBOOK · RB-03 restore database when data loss, corruption, failed migration owner on-call engineer · approver: CTO rpo/rto 15 min / 60 min 1 freeze writes: scale api to 0 2 restore to new instance from PITR, time T 3 verify row counts against ledger (script) 4 switch endpoint; scale api to 2 5 log the change with rollback: re-point to old RESTORE DRILL · 2025-11 · evidence start 10:02 restore complete 10:19 (17 min) row counts 118 / 118 tables match switch 10:23 total 21 min, under RTO 60 min screenshots: 6 · signed by: on-call, CTO CHANGE LOG · written before it ran # Change Rollback Result When C-41 enable PIM for Global Admin disable role policy ok Tue 09:10 C-42 DNS: move apex to new host restore old records ok Tue 14:00 C-43 RDS parameter group v2 revert to v1 ok Wed 08:30 C-44 WAF managed rules on off ok, 0 false hits Wed 11:15 C-45 S3 block public access, all accounts per-bucket exception ok Thu 09:00