Security Trade-offs in an Engineering Roadmap: A Framework for the Conversation
Security work competes with feature delivery on the same roadmap. A structured approach to making the trade-off explicit and defensible to both engineering and product.

Security work and feature delivery share the same roadmap rows, the same engineers, and the same quarter boundaries. Pretending otherwise produces either silent neglect or performative checkbox security. This note is a framework I have used in roadmap reviews to make trade-offs explicit — defensible to product, legible to engineering, and honest about what we are not doing.
For communicating proposed work to leadership, pair with writing RFCs that get read. For org design context on who owns these calls: hiring ICs vs managers.
The conversation we were failing to have
Typical pattern before I formalized this:
- Security team files 40 Jira tickets tagged P1 from a pen test
- Product says "we ship OAuth in Q3 regardless"
- Engineering silently fixes the easy eight tickets, deferrs the rest
- Nobody writes down the accepted risk on the deferred thirty-two
Six months later, an incident touches one of the deferred items. Postmortem asks "why was this known?" Everyone was busy. That is not an answer.
The fix is not "security wins every fight." The fix is documented trade-offs with owners and expiry dates.
Framework: risk register tied to roadmap items
Every roadmap initiative gets three security fields in the planning doc (Notion table, Jira custom fields, whatever you use):
- Exposure class — what breaks if we ship without addressing X
- Mitigation options — with effort estimates in engineer-weeks, not story points
- Decision — ship with mitigation A, defer B with acceptance, or block
No fourth option of "we'll get to it." Defer requires a named acceptor (usually EM or PM, not the security engineer alone).
Exposure classes (keep it coarse)
| Class | Definition | Example |
|---|---|---|
| E1 — Credential / data breach | User or admin secrets exfiltrated | SQLi in admin panel |
| E2 — Service integrity | Data corrupted, unauthorized writes | Missing authz on write API |
| E3 — Availability | Sustained outage from attack | Unbounded regex DoS |
| E4 — Compliance / contractual | SLA or regulatory breach | Missing audit logs for SOC2 |
| E5 — Latent / defense in depth | Bad practice, no known exploit path | Missing CSP header |
E1 and E2 block by default unless acceptor is VP-level with written sign-off. E5 almost never blocks a feature launch — but it goes on the register with a revisit date.
Effort estimation that product trusts
Security tickets estimated in "points" are meaningless to PMs. I translate to:
- S (< 1 eng-week): config change, dependency bump, add header middleware
- M (1–3 eng-weeks): authz model extension, new validation layer
- L (3–8 eng-weeks): architectural change (tenant isolation, mTLS mesh)
- XL (> 8 eng-weeks): replatforming trust boundary
When a pen test finds 40 issues, roll them into themes before roadmap negotiation:
- "Admin API missing object-level authz" — L, E2
- "Outdated lodash in internal tool" — S, E5 (not customer-facing)
- "Session fixation on legacy login path" — M, E1
Product can prioritize themes. Engineering can staff themes. Security can stop filing duplicate tickets.
The trade-off conversation script
In roadmap review, for each conflict:
"We can ship Feature X in Q3 if we accept deferred theme Y until Q1.
Deferral owner: [PM name].
Revisit trigger: before next pen test / if admin API usage exceeds N users.
Compensating control: WAF rule Z (partial, documented false positive rate)."
Write that paragraph in the decision log. Slack threads do not count.
Worked example
Feature: Public API for partner integrations (Q3 commitment, contractual).
Finding: Rate limiting is per-API-key but not per-tenant; one compromised key can exhaust shared Redis pool (E3).
Options:
- A. Ship with documented partner onboarding + manual key rotation (S) — partial
- B. Add tenant-scoped rate limit buckets (M, 2 weeks)
- C. Delay API GA to Q4, ship private beta only (schedule hit)
Decision we took: B slips GA by one week; PM accepts with partner comms template ready. Documented in RFC-214 "Public API Security Posture."
What we did not do: Ship on original date with a verbal "we'll add rate limits later."
Metrics that help without becoming vanity
DORA metrics do not capture security posture. I track three operational numbers quarterly:
- Mean age of open E1/E2 findings — target < 30 days
- Percent of roadmap items with security decision recorded — target 100% for customer-facing
- Compensating controls with expiry — count; goal is zero expired without re-review
I do not report "vulnerabilities closed" without severity context. Closing 100 E5 tickets before a audit is theater.
When to block (rare, loud)
I block launches for:
- Known E1 with public exploit (CVE with PoC, reachable path)
- Secrets in git history not rotated
- Production database reachable from internet without auth (yes, it happens)
Block means EM + security + PM in a 30-minute call, same day. Outcomes: fix, delay, or accept with exec sign-off. No async negotiation on E1.
Anti-patterns I have seen
Security as staff function with no roadmap seat. Findings appear after commitments are made. Fix: security liaison attends quarterly planning, read-only, two weeks before lock.
"Shift left" without capacity. Every team owns security but nobody has hours allocated. Fix: 10–15% capacity line item on platform team or rotating "security sprint" per quarter.
Checkbox compliance. SOC2 auditor wants a policy; team writes policy; nobody follows runbook. Fix: tie compliance artifacts to automated checks (terraform policy, CI gates) or do not claim compliance.
Infinite deferral. "Accepted risk" with no expiry becomes permanent. Fix: calendar reminder at 90 days; auto-reopen if acceptor still employed.
Template snippet (copy into your RFC)
## Security posture
| Theme | Exposure | Effort | Decision | Owner | Revisit |
|---|---|---|---|---|---|
| Object-level authz on /admin | E2 | M | Ship in Q3 wk 2 | @em | 2024-10-01 |
| Legacy session cookies | E1 | M | Block until fixed | @sec | — |
| CSP missing on marketing | E5 | S | Defer Q4 | @pm | next pen test |
What I would do next
Automate the register from pen test CSV imports into Jira epics with exposure class pre-tagged. Manual transcription is where findings die.
Run a quarterly "accepted risk audit" — 30 minutes, list every deferral older than 90 days, kill or renew each one.
Related
RFC writing for making security decisions readable. Hiring ICs vs managers for where security ownership should sit as you scale.
Manish Bookreader
Electronics enthusiast, Embedded Systems Expert, Linux/Networking programmer, and Software Engineer passionate about AI, electronics, books, and cooking.

