Software Assurance in the Agile Software Development Lifecycle
Software Assurance is fundamental to the systems engineering process and ensures high quality software is delivered with limited vulnerabilities. In order to achieve this goal software assurance must be applied across the full Software Development Lifecycle (SDLC). Many organizations, such as the National Institute of Standards and Technology (NIST), have detailed this process, but do so in a traditional waterfall approach . In order to transition this software assurance approach to an Agile software development lifecycle it is important to utilize not only the cadence for development and testing but also the cross functional team structure to reinforce your assurance practices. Figure 1 provides an overlay of software assurance best practices onto a single Agile development sprint. Although similar to a standard development lifecycle each phase has a unique Agile implementation that provides a structure for assurance practice.
The foundation for software assurance is defined with the requirements. Requirements should be written and decomposed focusing not only on what the system needs to do functionally, but how it will be protected. To inform these decisions, programs model threats, complete criticality analysis, and define functional and non-functional software security requirements. Due to the level of requirements that must be defined prior to Engineering & Manufacturing Development (EMD) phase of the DoD acquisition lifecycle, programs should have a more complete definition of software assurance requirements than a typical Agile development effort.
While requirements may be more fully defined it does not mean they are fully understood or even evolved to meet the changing threats required to complete the mission. Prior to the start of an Agile sprint, the team reviews the requirements for any new capabilities being developed. From an assurance perspective all relevant security requirements should be documented and included in these user stories for the upcoming sprint. In addition to new requirements, all acceptance criteria for sprint work should be included in the user stories, referred to as the definition of ready, to ensure that stories are actionable for developers. This includes code reviews, completion of unit tests, and use of static analysis tools prior to delivery of new code. While requirements may be more fully defined it does not mean they are fully understood or even evolved to meet the changing threats required to complete the mission. Prior to the start of an Agile sprint, the team reviews the requirements for any new capabilities being developed. From an assurance perspective all relevant security requirements should be documented and included in these user stories for the upcoming sprint. In addition to new requirements, all acceptance criteria for sprint work should be included in the user stories, referred to as the definition of ready, to ensure that stories are actionable for developers. This includes code reviews, completion of unit tests, and use of static analysis tools prior to delivery of new code.
Along with defining requirements, the team should make design decisions prior to the first sprint and then review these designs with each sprint planning meeting. This includes following secure architectural design patterns and doing an architectural analysis of risk. Once architectural drawings and system modeling is complete, the team can make changes and reassess risk with each subsequent sprint planning session. This also allows programs to identify any new vulnerabilities affecting the initial design and plan rework efforts based on the prioritized backlog. The built-in quality expected of Agile development relies on the ability to refactor existing code to address changes in requirements. As threats change and design pattern vulnerabilities are discovered, the flexibility to refactor becomes far more important in the development of a secure system.
An Agile development methodology is only as good as the tools and environments used to facilitate continuous integration. It is also these tools and environments that enable software assurance practices to be incorporated into the software development. All members of a development team can have access to an integrated development environment (IDE) to ensure secure coding standards are being followed. Additionally check-in procedures for new code can require static analysis of new code, code review by peer programmers, and origin analysis to determine the source and existing vulnerabilities of all code added to the stream. Integrated team testers should identify vulnerabilities and ensure they are resolved prior to check-in. Daily stand-ups include representatives from cross-functional teams including database administrators, architects, and Information Assurance to address system assurance and other related questions to ensure development teams are aware of potential sources of vulnerabilities.
The effectiveness and efficiency of Agile teams relies on the automation of day to day procedures. Automation is also key to software assurance because it enables a system to be thoroughly and accurately tested for vulnerabilities on a continuous basis without overburdening a test team. This automation begins with the development team and then is provided for reuse later in the lifecycle. Once automated, unit and regression testing can take place as needed to ensure working software that is free of vulnerabilities. The practice of assuring software, once thought to be burdensome to software developers, can be aligned with the Agile cadence and integrated into development, compilation, and delivery tools to become a standard part of the development process. In return, vulnerabilities are found earlier and fixed prior to delivery to the test environment. As a side effect, developers learn secure coding practices through experience and reduce similar issues from occurring in the future.
Through Agile development, parts of the test process are moved into the software development phase to fix defects prior to integration into the code base. This process formalizes test cases and often automates them for reuse. Independent Verification and Validation (IV&V) teams use existing test and develop additional testing to discover defects prior to user acceptance testing. Through Agile’s continuous integration model, testing can occur continuously with testers having access to the code base in an environment designed to mirror the operational environment. Static and dynamic analysis tools can scan and examine the entire code base. These results, along with penetration testing, provide direct feedback to developers and increases defect/vulnerability reporting into the product backlog.
At the end of each sprint all working software is delivered to one or multiple test environments. Test teams work a single sprint behind development to identify defects and vulnerabilities that can be prioritized in the program backlog for the next release. In addition to test teams, Agile relies on the involvement of users in the sprint process. Along with the ability to provide sprint demo’s the continuous development environment and automated deployment allows users the opportunity to test functioning code before release to production. This adds an additional layer of assurance as users can determine if software functions as intended and only as intended without simply relying on requirements. Through the integrated development environment, users can also provide feedback in the form of defects to the product backlog and development teams.