Skip to main content
U.S. flag

An official website of the United States government


General Security Standards

In the Federal government, the principal law governing the security of information systems is the Federal Information Security Modernization Act (FISMA). For more information on FISMA, check out the , external,FISMA Implementation Project , which will help you stay up to date and in the know about all things FISMA. If you're inclined to see TTS' interpretation of FISMA from a user-center approach, take a look at a previous project from the TTS Tech Portfolio and known as , external,FISMA Ready.

Most of the security practices have been integrated into the ATO portion of this guide and summarized in this , external,TTS-only, slide deck from one of the 18F engineers. Here are a few pointers to get you started:

  • DevOps isn't a team at TTS, but a skillset. We are all responsible for the security and operations of our systems.
  • The security of our users' information is paramount, even moreso when it is personally identifiable information (PII). The types of information your system may process helps determine the type of ATOs available to you and whether or not you will need to conduct a Privacy Impact Assessment (PIA).
  • Be wary of systems that:
    • trust un-sanitized information from the internet
    • do not encrypt data, both at rest and in transit
    • may be subject to privilege escalation
    • other items from the , external,OWASP Top 10

Security Scanning

Security scanning is separated into a few categories:

  • Static: Static Code Analysis (SCA) is similar to the , external,linters that many developers use on a day-to-day basis. While many linters focus on stylistic concerns, we are interested in those tools that target security flaws.
  • Dynamic
    • Active
      • Antivirus and malware scanning
      • Infrastructure-level scan (done at the level)
      • Penetration test
    • Passive: Monitors network traffic, but does not generate its own traffic.


Alerts come in one of four categorizations:

  • Low and Medium can be resolved after the ATO is granted.
  • High and Critical must be resolved before the ATO is granted.

Any false positives should be documented as such, through an "ignore" file (e.g. with a note in , external,Brakeman) or with your ATO-related documentation.

ATO Scanning

Getting ready to scan

The system's technical stack needs to be relatively stable before authorization.

If, during testing, the system performs:

  • user authentication or authorization
  • back-end administrative functions
  • encryption

...then those features must be complete before an authorization will be given. Note that the use of common web frameworks and HTTPS resolves these issues in almost every case.

Ensure that your site is scannable by automated tools. For example, if you have a single-page app use the pushState to make site URLs friendly to automated tools.

Lastly, make sure the README file in your repo is fully up to date and clearly explains what the system does and why at a high level. You should also include the above information in your README.

Greybox testing

Once you are ready, the TTS-only, GSA OCISO team will start both automated and manual scanning and testing. This includes:

For greybox testing, the testing team has significant (but not necessarily complete) knowledge of how the system works, as opposed to black box testing, where they have zero knowledge, or white box testing, where they have complete knowledge.

All of these tests must be conducted on an environment that is identical to production and ideally is set up specifically for this scanning process. This also requires creating a stable release branch. You can continue working on main and deploy builds from main to a development environment.

Expectation management

Overall, if no vulnerabilities are found, this process has been taking approximately 2 weeks for test preparation and System Security Plan writing and 2 weeks for greybox testing and , external,signature. FISMA Moderate and FISMA High will require additional time.

Since the time it would take to resolve vulnerabilities is not known until a vulnerability is identified, it is strongly recommended that no expectations are set with Federal partners or GSA stakeholders when public testing will begin. Instead, we recommend that the authorization process is seen as part of the delivery process and your definition of "done".

After the system has been authorized, you can then begin planning a public roll out of your system.

Static Analysis

Static analysis is an important part of the development process, and is required for ATO. There are two main types of static security testing that needs to be done:

  • Dependency analysis, where the Ruby gems, Python modules, and JavaScript packages your app uses are checked against a list of known vulnerabilities.
  • Code security analysis, in which your code is checked against a list of antipatterns.

There are tools for JS, Ruby, and Python, and you are encouraged to set up this scanning early on in the development cycle to prevent unexpected delays when it's time to get your ATO. Note that there are many tools out there for doing code style linting - see the , external,Development Guide for recommendations. This page is specifically security-focused.

Recommendations by language

Language Dependency analysis Code security analysis
Go , external,Snyk , external,Go Meta Linter, with the security-related , external,linters (like , external,SafeSQL, if you're doing SQL queries) enabled / , external,CodeQL
JavaScript , external,GitHub* , external,eslint-config-scanjs / , external,eslint-plugin-security / , external,CodeQL
Python , external,GitHub* , external,Bandit with the provided , external,config file; , external,engine for Code Climate / , external,CodeQL
Ruby , external,GitHub* , external,Code Climate or , external,Hakiri - Rails only

* Enabled automatically for repositories in , external,TTS GitHub organizations through , external,ghad.

Dependency analysis

Use one of the services above, which should support adding public repositories yourself. If you need scanning on a private repository, , external,TTS-only, file an issue in the Infrastructure repo.


When starting a new project for an agency partner, consider , external,creating a new Snyk organization for your project and , external,invite the agency partners (in addition to the TTS team). This will facilitate the project's hand-off in the future.

For repositories which include multiple dependency manifests (e.g. due to multiple sub-projects or crossing languages), be sure to configure Snyk to track each dependency file. By default, Snyk's import will stop after finding the first dependency manifest.

Code analysis

This is commonly referred to as "static analysis". Code analysis can be done by a service (recommended), or within your existing continuous integration tool. Additional configuration information available below.

Config files

Basic config files for some static analysis tools can be found in the , external,compliance-toolkit repo. These currently are little more than the default settings, but the recommendations may change. If you find a test that you believe is invalid, file an issue in the repo.

We are especially interested to know if you get lots of false positives. We believe the default config files will grow and evolve, but the most up-to-date versions will always be found in the repo.

More advanced configuration options for all the tools can be found in their respective docs.

Dynamic Scanning

In order for an application to get ATO, it needs to meet more than a minimum level of application security, so the application team needs to run both static and dynamic security scans and document good results. Running a "dynamic" scan means running a program that analyzes a live running application for common vulnerabilities.

As part of the process of getting an ATO at TTS, your application team will need to set up , external,OWASP ZAP to do dynamic vulnerability scanning of your application. ZAP can function as either an active (Spider & Attack options) or a passive (man-in-the-middle/proxy) scanner, but is usually used as a combination of both. If you (or another person on your application team) has questions about setting this up, ask #infrastructure for help.

ZAP home screen


You will need a running application to test, which you will want to be as production-like as possible—ideally a staging environment. Running a scan can cause a spike in requests and errors, so inform your team and , external,TTS-only, #infrastructure if you are going to run it on a production site.

We gave an introduction to ZAP talk as part of our engineering tech talks series Slides and additional information available , external,here.

Using the , external,Quick Start is a good way to get a basic idea of what ZAP does.


  1. , external,Set up ZAP as a proxy.
    • Unfortunately, the "Plug-n-Hack" extension mentioned on the Quick Start page is , external,currently non-functional.
    • If the browser gives you a certificate error (e.g. "This site uses HTTP Strict Transport Security (HSTS) to specify that Firefox may only connect to it securely."), you will need to install ZAP's root certificate.
      • In ZAP, go to Tools->Options->Dynamic SSL Certificate and click the Save button to save the certificate to your computer.
      • You will then need to install the certificate. For Firefox, go to Preferences->Advanced>Certificates->View Certificates->Import to import the certificate you saved from ZAP.
      • For additional information see ZAP's , external,documentation on Dynamic SSL Certificates.
  2. Seed the scanner.
    1. Navigate through the various types of pages/interactions on your site, including signing in. You should see domain name(s) start to show up under the Sites list.
    2. For each of the domains in the Sites list that you control (i.e. not
      1. Right-click the domain to bring up the context menu.
      2. Select Include in Context->Default Context.
      3. In the Session Properties window that pops up, click OK.
  3. Run the spider.
    1. In the menu bar, click Tools->Spider....
    2. Click New Scan.
    3. Next to Starting point, click Select....
    4. In the Select Node window, click Default Context, the Select.
    5. Click Start Scan.
    6. You should see the Spider table fill up with results, but the domains you don't control should say OUT_OF_CONTEXT.
  4. If your site uses AJAX, run the , external,AJAX Spider.
  5. Run the actual scan.
    1. In the menu bar, click Tools->Active Scan....
    2. In the Active Scan window, follow the same Starting point steps as above.
  6. View the alerts.
    1. Click the Alerts tab.
    2. Above the Alerts list, click the target icon (so that it turns red) to Show only URLs in scope.
  7. Investigate the listed alerts.
  8. Export the results.
    1. In the menu bar, go to Report -> Generate HTML Report.

Examining the Results

The Spider

spider results

As configured, the Spider does not follow links to other domains or subdomains. If your project uses either (for example, you use S3 for assets, or the api is at a different sub domain), you will want to click the options icon (shaped like a gear ⚙️) and update the options to include the domains & subdomains within the scope. There is a guide available for those options , external,here.


alert results

The Alerts pane lists all alerts discovered while scanning the site. As described on the alerts page, the red and orange-flagged alerts must be taken care of before the application can be ATO'd. You have a little more flexibility when dealing with the yellow and blue flags, but all of them must be either corrected or, in the case of false positives, documented.

Optional: When you get false positives, you can , external,file issues with the ZAP project to help them improve the alerting rules to prevent false positives.

If you're running the attack against a local server you may see some alerts that you wouldn't see on Debugging web servers are more 'chatty' about errors than production servers.

Other Tools Within ZAP


, external,"Fuzzing" refers to feeding a large amount of random (and/or potentially malicious) data to an application with the intention of finding vulnerabilities related to poor error handling or incomplete input validation. Typically, fuzzing is used on query parameters and form fields.

Any request in ZAP can be fuzzed. Simply right click on it, select Attack -> Fuzzer. Read more about ZAP's Fuzzing capabilities , external,here.

More Information

The lead engineer for OWASP ZAP, Simon Bennetts, has recorded a number of , external,useful YouTube videos, and that's probably the best place to start learning ZAP.

The , external,ZAP User Guide is phenomenal. If you run into an issue, this should be the first place you check.

The , external,OWASP Vulnerable Web Applications Directory has a great list of (intentionally) vulnerable targets that are useful for testing the capability of ZAP.

We are currently collecting best practices for using ZAP. If you have a particular approach, extension, or option that you find effective, , external,open an issue!


Organized by language.

, external,Node.js

, external,Express

, external,Sails

, external,Python

, external,Django

See also:

, external,Flask

See also:

, external,Ruby

, external,Rails

More info:

, external,Sinatra/, external,Padrino

More info:

Are we missing guidelines for the framework you're using, or think our guidelines could be improved? , external,Open an issue!

Multi-Factor Authentication

All TTS systems requiring authentication must use multiple factors. Examples of multi-factor authentication (MFA) include, but are not limited to:

Systems in the pre-assessment phase do not require MFA.

Return to the top of the page ^

An official website of the U.S. General Services Administration

Looking for U.S. government information and services?
, external,Visit