Tag Archive for: dod

Posts

Security User Stories How-To – for product managers and developers

I wrote some time ago about “How to create security user stories” and I received in the meanwhile a lot of good feedback and questions about it.

For these reasons, I decided that it is time to write again on the topic, this time with focus on two importat groups in any software developer team: Product Managers and software developers.

 

What a Security User Story actually is and why it needs modification for security

A regular user story captures what a user wants to do and why, following the format:

  • As a [role], I want [goal], so that [benefit].

A security user story does the same thing, but the “role” is often a threat actor, a security control, or a compliance requirement — and the “benefit” is about preventing harm rather than enabling convenience. Most teams write functional stories and then bolt security on at the end as a checklist. That approach fails because security requirements that arrive late in a sprint get trimmed, deferred, or implemented incorrectly because nobody thought about them during design.

The correct mental model is this: security stories live in the same backlog as functional stories, they get estimated, they get accepted or rejected based on clear criteria, and they block a release when they aren’t done. They are not a separate audit artifact. They are not a penetration test report reworded as tickets. They are engineering requirements written with enough precision that a developer can implement them and a tester can verify them without reading anyone’s mind.

For security work, the format above breaks down quickly because it was designed for positive outcomes — a user wanting access to something. Security stories often describe preventing something, enforcing a constraint, or ensuring a system behaves correctly under adversarial conditions.

A more useful format for security stories adds a threat context and a verification condition:

As a [role or attacker], I want [action or capability] so that [outcome] — therefore the system must [control] which can be verified by [test condition].

The verification condition is what separates a useful security story from a wish. If you cannot write a concrete test that passes or fails, the story is not ready to be worked on.

What Product Managers are responsible for

The product manager’s job is not to write the technical implementation details. It is to make security requirements visible, prioritized, and connected to real risk. PMs tend to treat security as either non-negotiable compliance overhead or as something the security team handles separately. Both attitudes produce bad outcomes.

In the “Ideal world”

The PM writes the threat context. This means thinking like an attacker long enough to articulate what someone with bad intentions could do with the feature being built. A PM building a file upload feature should be asking: who uploads files, what happens to those files after upload, and what is the worst realistic thing that happens if an attacker controls the file content. That thinking produces a security story. The absence of that thinking produces a feature with a file upload vulnerability discovered six months later.

PMs also own prioritization. A security story that prevents account takeover ranks higher than one that adds a password complexity rule nobody will read. That judgment requires understanding the actual risk exposure of the product, which means PMs need enough security literacy to have the conversation with their security team rather than outsourcing the entire decision.

But this is just “ideal” – which means it almost never happens. Or, at least, I have never seen this done in 25 years of product management.

In the “real world”

The PM doesn’t care about security. For the PM, it is by default assumed that the technical team will implement the feature secure by design, by default and by deployment.

This “not my concern” attitude creates a lot of friction in the development teams.

So, then, who creates the security user story?

 

What Developers Are Responsible For

The developer’s job is to take a security story and implement the control correctly, then write the acceptance criteria into an automated test. Developers often receive vague security requirements — “ensure input is validated” or “use secure coding practices” — and have no way to know whether their implementation is correct because the requirement has no measurable outcome.

When a developer receives a well-formed security story, the implementation work splits into two parts. First, the technical control: how does the code actually enforce what the story requires. Second, the negative test: does the code fail correctly when the control is bypassed or when an attacker sends unexpected input?

Developers should be writing both happy-path and adversarial tests for security stories. If the story says “the system must reject file uploads where the MIME type does not match the file extension,” the developer writes a test that sends a PHP file renamed as a JPEG and confirms the server returns a 40x code. That test becomes a regression guard. It will catch the next person who refactors the upload handler and accidentally removes the validation.

Example developer-implemented security story with acceptance criteria:

As a developer implementing the password reset flow, I need to ensure the reset token cannot be guessed or reused so that an attacker who intercepts or brute-forces the URL cannot take over an account.

Acceptance criteria written by the developer before coding begins: the reset token must be generated using a cryptographically secure random function producing at least 128 bits of entropy. The token must be stored as a bcrypt hash, not plaintext. The token must expire 15 minutes after generation. The token must be invalidated immediately after it is used once. A request with a token that was already used must return a 400 with no indication of whether the token was valid. These criteria become the test suite, not the documentation.

Hard, isn’t it? A lot of knowledge is required about crypto, OAuth2, etc.

Can developers do this?

How to implement this in practice

The first step is adding a threat modeling checkpoint to the definition of done (DoD) or at least in the checklists for development phases. Before a story moves into a sprint, the team asks: does this story touch authentication, authorization, data storage, external input, or external communication? If yes, a corresponding security story must exist in the backlog before the functional story is pulled in.

The second step is building a library of security story templates for common patterns. You don’t need to invent this library, there are plenty of resources available online.

Start from the common frameworks like OWASP, STRIDE, NIST, etc:

  • SQL injection prevention,
  • CSRF protection,
  • secure file handling,
  • secrets management, and rate limiting
  • how are Confidentiality, Integrity, Availability (CIA) affected at various stages, with different types of data

all appear repeatedly across features. A template gives the team a starting point rather than expecting developers and PMs to derive the requirement from scratch every time.

The third step is treating failed security acceptance criteria the same as failed functional tests. If a security story is not done, the feature is not done. This requires management buy-in, but it is the only way to prevent the pattern where security stories accumulate in the backlog indefinitely while features ship without their corresponding controls.

The fourth step is reviewing security stories in sprint retrospectives. Not the controls themselves, but the process: were the stories specific enough to implement, did the acceptance criteria hold up during code review, did any security debt get created because the story was underspecified. That feedback loop is what makes the team better at writing them over time.

 

The Three Most Common Failures

The first failure is writing security stories as restrictions without context. “The system must not allow SQL injection” tells a developer nothing actionable. It does not say where the injection risk exists, which inputs are affected, or how to verify the control is working. The correct version identifies the specific input vector, the parameterization or ORM requirement, and the test that confirms raw SQL cannot be injected through that input.

The second failure is writing security stories only after a penetration test. Pen test findings are useful, but treating them as the primary source of security stories means the team is always reacting to vulnerabilities in shipped code rather than preventing them during design. Security stories belong at feature inception, not at audit time. Best is to update the templates after each set of findings, so that you don’t repeat the issues next time.

The third failure is accepting security stories with vague verification conditions. “The login must be secure” cannot be tested. “The login endpoint must lock an account for 30 minutes after 5 consecutive failed attempts, respond with a 429 on the sixth attempt, and not disclose whether the lockout is due to the account not existing or the password being wrong” can be tested. The difference between these two is the difference between a team that thinks about security and a team that actually builds it.

 

Instead of conclusions

So, who is expected to create the security user stories?

Usually, PMs don’t know how and don’t think it is their problem anyway.

Most developers have not beein trained into thinking offensive security. Actually, vast majority never even had a formal training in writing secure code for their platform.

I think that the answer depends on the organization size, type and focus.

Small organizations (< 50 developers) : everybody should work together, use as much as possible templates from tools and online resources.

Medium organizations (51-200 developers) : you should have dedicated people with formal training in security. It can be that they are occupying the role of PM or developer or architect. Start from the same things as small sized organizations and adapt everything for your needs, if you can.

Large organizations (200+ developers) : you should have dedicated security architect, security developers and other roles trained in secure development. You should have your own set of templates and tools to be used. Your SDLC must include mandatory security user stories.

The post Security User Stories How-To – for product managers and developers first appeared on Sorin Mustaca – Security & Technology.

Guide for delivering frequently software features that matter (series) #1/2: the Pillars of successful frequent delivery

Click below for the podcast version (AI generated):

Guide for delivering frequently software features that matter: the three Pillars of successful frequent delivery

If you’re a software engineer older than 30 years, then you definitely have worked following a non-agile methodology.

Those methodologies are based on a fixed structure, a lot of planning, and hope that everything will go as planned. And they never worked 🙂

 

Small bets, less risk

After helping many teams transform their delivery approach over the past 2 decades, I’ve learned that the most successful software projects share one trait: they deliver working software early and often. Think of it like learning to cook—you taste as you go rather than waiting until the entire meal is prepared to discover it needs salt – or to discover that it has too much salt.

Scrum’s power lies in its ability to turn software development from a high-stakes gamble into a series of small, manageable bets.  It basically lowers the risk of creating something that is a failure before it is even released.

Instead of spending months building features that might miss the mark, you deliver value every 2 weeks and course-correct based on real user/stakeholder feedback.

 

The Three Pillars of successful frequent delivery

1. Sprint Planning that actually delivers value

Here’s where most teams go wrong: they focus on completing tasks instead of delivering outcomes.

In my experience, the magic question that transforms Sprint planning is: “What could we deliver to users at the end of this Sprint that would make them say ‘this is useful’?”

Or maybe, if you’re not that far, think in terms of: what do we have to do in order to be able to have something to show to customers/users/stakeholders?

This shift in thinking leads to what I call “vertical slicing”—delivering complete, end-to-end functionality rather than building in horizontal layers.

Think of instead of spending a sprint on “database framework,” you deliver a complete feature like “user login” that touches database, business logic, and user interface.

Or, instead of having a “GUI framework”, implement a GUI element and make it testable. You will still need to put the base of the GUI framework, but you will likely (or hopefully) implement only those elements needed to deliver that one element.

 

2. Your Definition of Done (DoD) is your safety net

The Definition of Done isn’t bureaucracy—it’s your insurance policy against the dreaded “90% complete” syndrome. I’ve seen too many teams rush to demo features that weren’t actually ready for users, creating technical debt that haunts them for months.

A solid Definition of Done includes peer reviews, automated tests, security checks, performance validation, and sometimes stakeholder approval.

Think of it as your quality gateway: nothing passes through unless it meets production standards.

 

3. What enables speed

CI/CD

Continuous Integration isn’t just a nice-to-have—it’s the foundation that makes frequent delivery possible. When code is integrated and tested multiple times, you eliminate the integration nightmares that plague traditional development.

Anything that is manual, especially testing, takes more time on the long run. And in software development you are running a multi stage marathon. Invest in automated End-To-End testing and you invest the time once, not every release cycle.

 

Main branch development

The teams who excel at frequent delivery have embraced “trunk-based development” where everyone works from the main branch. This forces smaller, more frequent commits and prevents the merge conflicts that can derail Sprint goals.

You might say that this is not always possible – and I even agree. Sometimes you need to branch in order to allow parallel development of larger features, which you don’t want to deliver step-by-step. While I don’t like this approach, I understand that sometimes it makes sense.

But, even in such cases, you can apply the same strategy on the parallel branch: make many small commits so that you can release often and test often.

 

I’ll stop here for now, but as you can see, there are many challenges that stop teams from releasing often.

I’ll address this in the next article from this series.

The post Guide for delivering frequently software features that matter (series) #1/2: the Pillars of successful frequent delivery first appeared on Sorin Mustaca on Cybersecurity.

Guide for delivering frequently software features that matter (series)

If you’re a software engineer older than 30 years, then you definitely have worked following a non-agile methodology.

Those methodologies are based on a fixed structure, a lot of planning, and hope that everything will go as planned. And they never worked 🙂

 

Small bets, less risk

After helping many teams transform their delivery approach over the past 2 decades, I’ve learned that the most successful software projects share one trait: they deliver working software early and often. Think of it like learning to cook—you taste as you go rather than waiting until the entire meal is prepared to discover it needs salt – or to discover that it has too much salt.

Scrum’s power lies in its ability to turn software development from a high-stakes gamble into a series of small, manageable bets.  It basically lowers the risk of creating something that is a failure before it is even released.

Instead of spending months building features that might miss the mark, you deliver value every 2 weeks and course-correct based on real user/stakeholder feedback.

 

The Three Pillars of successful frequent delivery

1. Sprint Planning that actually delivers value

Here’s where most teams go wrong: they focus on completing tasks instead of delivering outcomes.

In my experience, the magic question that transforms Sprint planning is: “What could we deliver to users at the end of this Sprint that would make them say ‘this is useful’?”

Or maybe, if you’re not that far, think in terms of: what do we have to do in order to be able to have something to show to customers/users/stakeholders?

This shift in thinking leads to what I call “vertical slicing”—delivering complete, end-to-end functionality rather than building in horizontal layers.

Think of instead of spending a sprint on “database framework,” you deliver a complete feature like “user login” that touches database, business logic, and user interface.

Or, instead of having a “GUI framework”, implement a GUI element and make it testable. You will still need to put the base of the GUI framework, but you will likely (or hopefully) implement only those elements needed to deliver that one element.

 

2. Your Definition of Done (DoD) is your safety net

The Definition of Done isn’t bureaucracy—it’s your insurance policy against the dreaded “90% complete” syndrome. I’ve seen too many teams rush to demo features that weren’t actually ready for users, creating technical debt that haunts them for months.

A solid Definition of Done includes peer reviews, automated tests, security checks, performance validation, and sometimes stakeholder approval.

Think of it as your quality gateway: nothing passes through unless it meets production standards.

 

3. What enables speed

CI/CD

Continuous Integration isn’t just a nice-to-have—it’s the foundation that makes frequent delivery possible. When code is integrated and tested multiple times, you eliminate the integration nightmares that plague traditional development.

Anything that is manual, especially testing, takes more time on the long run. And in software development you are running a multi stage marathon. Invest in automated End-To-End testing and you invest the time once, not every release cycle.

 

Main branch development

The teams who excel at frequent delivery have embraced “trunk-based development” where everyone works from the main branch. This forces smaller, more frequent commits and prevents the merge conflicts that can derail Sprint goals.

You might say that this is not always possible – and I even agree. Sometimes you need to branch in order to allow parallel development of larger features, which you don’t want to deliver step-by-step. While I don’t like this approach, I understand that sometimes it makes sense.

But, even in such cases, you can apply the same strategy on the parallel branch: make many small commits so that you can release often and test often.

 

I’ll stop here for now, but as you can see, there are many challenges that stop teams from releasing often.

I’ll address this in the next article from this series.

The post Guide for delivering frequently software features that matter (series) first appeared on Sorin Mustaca on Cybersecurity.