Aller au contenu principal
Authentication, encryption, network security, application security, and secure system design.

Security

Authentication, encryption, network security, application security, and secure system design.

Secure System Design Principles

Security by Design, Not by Accident

Security fails when it’s an afterthought bolted onto a finished system. Secure system design makes security a design constraint from the start: every component gets its threat model, its least-privilege posture, and its place in a layered defense. This topic is the capstone of the security track — the lens through which you review any architecture.

Threat Modeling: Think Like the Attacker, First

Threat modeling is the discipline of enumerating who could attack what, how, and why — before the code exists. The standard framework is STRIDE, a mnemonic for the threat categories per component/data flow:

ThreatWhat it attacksExample
Spoofingauthenticityimpersonating a user/service
Tamperingintegritymodifying a request, a file, a JWT
Repudiationnon-repudiationdenying a transaction that happened
Information disclosureconfidentialityleaking data in a response/log
Denial of serviceavailabilityexhausting a resource
Elevation of privilegeauthorizationexploiting a bug to become admin

The workflow:

  1. Draw the data flow — components, trust boundaries, and where data moves.
  2. Walk each flow against STRIDE — for every arrow, ask each threat: could this happen here?
  3. Prioritize — by likelihood × impact (the famous “CIA” priorities: confidentiality/integrity/availability by data type).
  4. Design mitigations — each accepted threat either gets a control or is explicitly risk-accepted.

A data flow diagram plus a STRIDE walk is the highest-ROI security activity there is — it finds the dangerous paths (password flows, admin endpoints, payment data) before they’re built.

Least Privilege: The Overarching Law

Least privilege says every actor — a user, a service, a process, an IAM role, a container — gets exactly the permissions it needs and nothing more. The idea generalizes across every layer you’ve studied:

  • IAM/roles — a service uses a narrowly scoped role (s3:PutObject on one bucket), not *:*.
  • OS/process — containers run as non-root (Docker topic), apps don’t run as admin.
  • Databases — the app’s DB user can SELECT/INSERT/UPDATE its tables, not DROP DATABASE.
  • Secrets — each service sees only its own secrets, not a shared master key.

The payoff: a compromise is contained. A leaked container with least-privilege can’t destroy the fleet; a leaked admin key can. Least privilege is the structural defense — every other control assumes it.

Defense in Depth: Layers That Don’t Share a Weakness

No single control is perfect; defense in depth stacks independent layers so a bypass at one level is caught by the next:

  1. Edge: DDoS, WAF, rate limiting (Network Security topic).
  2. Transport: TLS everywhere, mTLS service-to-service.
  3. App: input validation, parameterized queries, CSP (AppSec topic).
  4. Identity: MFA, OAuth2/OIDC, RBAC (Auth topic).
  5. Data: encryption at rest, key management.
  6. Monitoring: audit logs, anomaly detection, alerting (Observability topic).

The layers must be independent — two layers that both rely on the same assumption (e.g., “requests are trusted”) are one layer. “We have a WAF” is not a substitute for “we parameterize SQL.”

Secrets Management

A secret is any credential that unlocks something: DB passwords, API keys, TLS private keys, OAuth client secrets, signing keys. The failure modes are famous and avoidable:

  • In source control — a committed .env or hardcoded key. This is a structural bug (history never forgets) — secrets scanning in CI and pre-commit hooks are the guardrail.
  • In container images — baked into a Docker layer (remember: layers are permanent, so the secret lives in every derived image).
  • In logs/config dumps — leaked to aggregators.

The fix is a secrets manager: Vault, AWS Secrets Manager, GCP/Azure equivalents. Secrets are stored encrypted, rotated on schedule, granted by policy (least privilege again: each app gets the secrets it needs), and injected at runtime (env vars, mounted files, or Vault agent) rather than baked into images. Add rotation: a leaked secret only matters if it’s still valid; rotation makes the leak’s shelf life short.

Secure Development Lifecycle

Security is a pipeline stage, not a person:

  1. Design — threat model, security review of the architecture.
  2. Develop — secure defaults, least privilege, no secrets in code, code review.
  3. CI/CD — static analysis (SAST), dependency scanning (SCA — the Log4Shell-style “vulnerable dependency” class), secrets scanning, container scanning.
  4. Test — dynamic testing (DAST), security test cases for the threat model.
  5. Deploy/Run — minimal permissions, encryption, audit logging, monitoring, incident readiness.
  6. Respond — an incident-response plan before the incident: who’s on call, how you contain, how you disclose.

The security review checklist that closes each phase:

  • Threat model updated for the changes?
  • Least privilege on every new role/service/secret?
  • No secrets in code, images, or logs?
  • All inputs validated, all queries parameterized, authz on every endpoint?
  • TLS everywhere, encryption at rest?
  • Audit logs capturing who-did-what?
  • Dependencies scanned, pinning in effect?

Incident Response for Security Events

Security incidents follow the same shape as ops incidents (SLO topic) with harder stakes:

  1. Detect — from audit logs, alerts, or (honestly) a vendor/customer notification.
  2. Contain — stop the bleed first: revoke the leaked credential, isolate the box, disable the account. Mitigation before forensics.
  3. Eradicate & recover — remove the attacker’s foothold, restore from trusted backups.
  4. Analyze — what was accessed, for how long, what data. This is where audit logs pay for themselves.
  5. Disclose & improve — notify affected parties, run the blameless postmortem, fix the root cause.

The critical operational habit: audit logs are the only way to answer “what did the attacker touch?” — if you don’t log access, the answer is “everything, we think.” Least privilege is what makes containment possible; logs are what make the analysis possible.

Practice Trajectory

  1. Draw a data flow for a small web app and run a STRIDE walk on the login, payment, and admin paths; list mitigations for each accepted threat.
  2. Audit an IAM setup: find the *:* role and rewrite it to least-privilege (which actions on which resources?).
  3. Move a hardcoded secret into a secrets manager, rotate it, and update the app to inject it at runtime.
  4. Add SAST, SCA, and secrets scanning to a CI pipeline and fix the findings they surface.
  5. Run a mock security incident: a leaked API key is detected — contain, rotate, audit what it could access, and write the postmortem.

When It’s the Right Tool

SituationTakeaway
Designing anything that touches dataThreat model it before you build
A compromise must not become a breachLeast privilege, everywhere, always
One control isn’t enoughDefense in depth with independent layers
“Where’s the DB password?”Secrets manager, injected at runtime, rotated
“What did the attacker touch?”Audit logs, or you can’t know