├── .allstar └── branch_protection.yaml ├── .bundler-version ├── .eslintignore ├── .eslintrc ├── .github └── workflows │ └── test.yml ├── .gitignore ├── .nvmrc ├── .prettierrc.json ├── .rspec ├── .ruby-version ├── .vscode └── settings.json ├── CODEOWNERS ├── CONTRIBUTING.md ├── Gemfile ├── Gemfile.lock ├── LICENSE.md ├── Makefile ├── README.md ├── SECURITY.md ├── _config.yml ├── _data ├── errors.yml ├── nav.yml ├── risc_incoming.yml ├── risc_outgoing.yml └── saml.yml ├── _includes ├── accordion.html ├── alert.html ├── dap.html ├── footer-navigation.html ├── footer.html ├── icon.html ├── icon_list.html ├── nav │ ├── item.html │ └── list.html ├── osc_analytics.html ├── risc_event.json ├── schema.html ├── search.html ├── snippets │ ├── auth_content │ │ ├── aal_values.md │ │ ├── deprecated_values.md │ │ └── service_levels.md │ ├── oidc │ │ ├── auth │ │ │ ├── failure.md │ │ │ ├── jwt.md │ │ │ ├── pkce.md │ │ │ └── success.md │ │ ├── certificates.md │ │ ├── logout │ │ │ ├── request.md │ │ │ └── response.md │ │ ├── token │ │ │ ├── jwt.md │ │ │ ├── pkce.md │ │ │ ├── response.md │ │ │ └── token.md │ │ └── user-info │ │ │ ├── request.md │ │ │ └── response.md │ └── saml │ │ ├── auth │ │ ├── request.md │ │ ├── request_example.md │ │ ├── response.md │ │ └── response_example.md │ │ └── logout │ │ ├── remote_logout.md │ │ ├── request.md │ │ ├── request_example.md │ │ ├── response.md │ │ └── response_example.md ├── support │ └── oidc.html ├── yaml └── yaml_download.md ├── _layouts ├── base.html ├── documentation.html ├── home.html └── not_found.html ├── _pages ├── 404.md ├── attributes.md ├── index.md ├── oidc │ ├── authorization.md │ ├── authorization │ │ └── pkce.md │ ├── certificates.md │ ├── getting-started.md │ ├── logout.md │ ├── token.md │ ├── token │ │ └── pkce.md │ └── user-info.md ├── overview.md ├── production.md ├── push-notifications.md ├── risc.json ├── saml │ ├── authentication.md │ ├── getting-started.md │ └── logout.md ├── security-events.md ├── support.md ├── testing.md └── user-experience │ ├── agency-logo.md │ ├── cancel-url.md │ ├── failure-proof.md │ ├── faq-content.md │ ├── getting-started.md │ ├── help-text.md │ ├── knowledge-articles.md │ └── sign-in-sign-out.md ├── _plugins ├── content_code.rb ├── content_typography.rb ├── copy_to_destination.rb ├── pretty_jsonify.rb └── yaml_content_disposition.rb ├── assets ├── img │ ├── agency-logo-contrast.png │ ├── dashboard_issuer.png │ ├── do_logo.svg │ ├── dont_logo.svg │ ├── global-sign-in.png │ ├── icon-system-status.svg │ ├── logo-guidelines.png │ ├── logo-white.svg │ ├── logo.svg │ ├── oidc-auth-flow.png │ ├── oidc-ial1-flow.png │ ├── oidc-ial2-flow.png │ ├── sign-in-button.svg │ ├── sign-in-menu.svg │ ├── sign-out-button.png │ └── sign-out-menu.png ├── js │ ├── anchor.js │ └── toggle_view.js ├── scss │ ├── _footer.scss │ ├── _not_found.scss │ └── main.css.scss └── yaml │ ├── document_classification_error.yml │ ├── image_resolution_error.yml │ ├── individual_state_error.yml │ ├── proofing.yml │ ├── proofing_vendor_error.yml │ └── sample_full_error.yml ├── favicon.ico ├── federalist.json ├── package-lock.json ├── package.json ├── scripts └── htmlproofer └── spec ├── e2e └── accessibility.test.js ├── page.md_spec.rb ├── risc.json_spec.rb ├── spec_helper.rb └── support └── matchers.rb /.allstar/branch_protection.yaml: -------------------------------------------------------------------------------- 1 | dismissStale: false 2 | -------------------------------------------------------------------------------- /.bundler-version: -------------------------------------------------------------------------------- 1 | 2.2.28 2 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | _site 2 | node_modules 3 | vendor 4 | assets/js/anchor.js 5 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "extends": ["plugin:@18f/eslint-plugin-identity/recommended"], 4 | "plugins": ["@18f/eslint-plugin-identity"], 5 | "env": { 6 | "browser": true 7 | }, 8 | "parserOptions": { 9 | "ecmaVersion": 2021, 10 | "sourceType": "module" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Tests 2 | on: 3 | workflow_dispatch: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | jobs: 9 | test: 10 | name: Specs 11 | runs-on: ubuntu-latest 12 | env: 13 | CI: 'true' 14 | steps: 15 | - uses: actions/checkout@v4 16 | - uses: ruby/setup-ruby@v1 17 | with: 18 | bundler-cache: true # runs 'bundle install' and caches installed gems automatically 19 | - uses: actions/setup-node@v4 20 | with: 21 | cache: 'npm' 22 | - name: Install NPM dependencies 23 | run: npm ci 24 | - name: Clean 25 | run: make clean 26 | - name: Build site 27 | run: make build 28 | - name: Run Ruby tests 29 | run: bundle exec rspec 30 | - name: Run HTMLProofer 31 | run: bundle exec scripts/htmlproofer --internal 32 | - name: Lint JavaScript 33 | run: make lint-js 34 | - name: Run NPM tests 35 | run: npm run test 36 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | _site/ 2 | node_modules/ 3 | .DS_Store 4 | .jekyll-metadata 5 | .sass-cache/ 6 | assets/uswds 7 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | lts/* -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "printWidth": 100 4 | } 5 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --color 2 | --format=documentation 3 | 4 | -------------------------------------------------------------------------------- /.ruby-version: -------------------------------------------------------------------------------- 1 | 3.2.5 2 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "git.ignoreLimitWarning": true 3 | } 4 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Team Ursula should always be tagged for review 2 | * @18F/identity-ursula 3 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Welcome! 2 | 3 | We're so glad you're thinking about contributing to an 18F open source project! If you're unsure about anything, just ask -- or submit the issue or pull request anyway. The worst that can happen is you'll be politely asked to change something. We love all friendly contributions. 4 | 5 | We want to ensure a welcoming environment for all of our projects. Our staff follow the [18F Code of Conduct](https://github.com/18F/code-of-conduct/blob/master/code-of-conduct.md) and all contributors should do the same. 6 | 7 | We encourage you to read this project's CONTRIBUTING policy (you are here), its [LICENSE](LICENSE.md), and its [README](README.md). 8 | 9 | If you have any questions or want to read more, check out the [18F Open Source Policy GitHub repository]( https://github.com/18f/open-source-policy), or just [shoot us an email](mailto:18f@gsa.gov). 10 | 11 | ## Public domain 12 | 13 | This project is in the public domain within the United States, and 14 | copyright and related rights in the work worldwide are waived through 15 | the [CC0 1.0 Universal public domain dedication](https://creativecommons.org/publicdomain/zero/1.0/). 16 | 17 | All contributions to this project will be released under the CC0 18 | dedication. By submitting a pull request, you are agreeing to comply 19 | with this waiver of copyright interest. 20 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | ruby File.read('.ruby-version').strip 4 | 5 | gem 'jekyll', '~> 4.3.0' 6 | gem 'jekyll-sass-converter', '~> 3.0.0' 7 | gem 'kramdown-parser-gfm', '~> 1.0' 8 | gem 'jekyll-redirect-from' 9 | gem 'jekyll-sitemap' 10 | 11 | group :test do 12 | gem 'html-proofer', '~> 4.0' 13 | gem 'rspec' 14 | gem 'rspec_junit_formatter', require: false 15 | gem 'nokogiri', '>= 1.10.5' 16 | end 17 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | addressable (2.8.7) 5 | public_suffix (>= 2.0.2, < 7.0) 6 | bigdecimal (3.1.8) 7 | colorator (1.1.0) 8 | concurrent-ruby (1.3.4) 9 | diff-lcs (1.5.1) 10 | em-websocket (0.5.3) 11 | eventmachine (>= 0.12.9) 12 | http_parser.rb (~> 0) 13 | ethon (0.16.0) 14 | ffi (>= 1.15.0) 15 | eventmachine (1.2.7) 16 | ffi (1.17.0) 17 | forwardable-extended (2.6.0) 18 | google-protobuf (4.28.3) 19 | bigdecimal 20 | rake (>= 13) 21 | html-proofer (4.4.3) 22 | addressable (~> 2.3) 23 | mercenary (~> 0.3) 24 | nokogiri (~> 1.13) 25 | parallel (~> 1.10) 26 | rainbow (~> 3.0) 27 | typhoeus (~> 1.3) 28 | yell (~> 2.0) 29 | zeitwerk (~> 2.5) 30 | http_parser.rb (0.8.0) 31 | i18n (1.14.6) 32 | concurrent-ruby (~> 1.0) 33 | jekyll (4.3.4) 34 | addressable (~> 2.4) 35 | colorator (~> 1.0) 36 | em-websocket (~> 0.5) 37 | i18n (~> 1.0) 38 | jekyll-sass-converter (>= 2.0, < 4.0) 39 | jekyll-watch (~> 2.0) 40 | kramdown (~> 2.3, >= 2.3.1) 41 | kramdown-parser-gfm (~> 1.0) 42 | liquid (~> 4.0) 43 | mercenary (>= 0.3.6, < 0.5) 44 | pathutil (~> 0.9) 45 | rouge (>= 3.0, < 5.0) 46 | safe_yaml (~> 1.0) 47 | terminal-table (>= 1.8, < 4.0) 48 | webrick (~> 1.7) 49 | jekyll-redirect-from (0.16.0) 50 | jekyll (>= 3.3, < 5.0) 51 | jekyll-sass-converter (3.0.0) 52 | sass-embedded (~> 1.54) 53 | jekyll-sitemap (1.4.0) 54 | jekyll (>= 3.7, < 5.0) 55 | jekyll-watch (2.2.1) 56 | listen (~> 3.0) 57 | kramdown (2.4.0) 58 | rexml 59 | kramdown-parser-gfm (1.1.0) 60 | kramdown (~> 2.0) 61 | liquid (4.0.4) 62 | listen (3.9.0) 63 | rb-fsevent (~> 0.10, >= 0.10.3) 64 | rb-inotify (~> 0.9, >= 0.9.10) 65 | mercenary (0.4.0) 66 | mini_portile2 (2.8.9) 67 | nokogiri (1.18.8) 68 | mini_portile2 (~> 2.8.2) 69 | racc (~> 1.4) 70 | parallel (1.26.3) 71 | pathutil (0.16.2) 72 | forwardable-extended (~> 2.6) 73 | public_suffix (6.0.1) 74 | racc (1.8.1) 75 | rainbow (3.1.1) 76 | rake (13.2.1) 77 | rb-fsevent (0.11.2) 78 | rb-inotify (0.11.1) 79 | ffi (~> 1.0) 80 | rexml (3.3.9) 81 | rouge (4.4.0) 82 | rspec (3.13.0) 83 | rspec-core (~> 3.13.0) 84 | rspec-expectations (~> 3.13.0) 85 | rspec-mocks (~> 3.13.0) 86 | rspec-core (3.13.2) 87 | rspec-support (~> 3.13.0) 88 | rspec-expectations (3.13.3) 89 | diff-lcs (>= 1.2.0, < 2.0) 90 | rspec-support (~> 3.13.0) 91 | rspec-mocks (3.13.2) 92 | diff-lcs (>= 1.2.0, < 2.0) 93 | rspec-support (~> 3.13.0) 94 | rspec-support (3.13.1) 95 | rspec_junit_formatter (0.6.0) 96 | rspec-core (>= 2, < 4, != 2.12.0) 97 | safe_yaml (1.0.5) 98 | sass-embedded (1.80.6) 99 | google-protobuf (~> 4.28) 100 | rake (>= 13) 101 | terminal-table (3.0.2) 102 | unicode-display_width (>= 1.1.1, < 3) 103 | typhoeus (1.4.1) 104 | ethon (>= 0.9.0) 105 | unicode-display_width (2.6.0) 106 | webrick (1.9.0) 107 | yell (2.2.2) 108 | zeitwerk (2.7.1) 109 | 110 | PLATFORMS 111 | ruby 112 | 113 | DEPENDENCIES 114 | html-proofer (~> 4.0) 115 | jekyll (~> 4.3.0) 116 | jekyll-redirect-from 117 | jekyll-sass-converter (~> 3.0.0) 118 | jekyll-sitemap 119 | kramdown-parser-gfm (~> 1.0) 120 | nokogiri (>= 1.10.5) 121 | rspec 122 | rspec_junit_formatter 123 | 124 | RUBY VERSION 125 | ruby 3.2.5p208 126 | 127 | BUNDLED WITH 128 | 2.5.9 129 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | As a work of the United States Government, this project is in the 2 | public domain within the United States. 3 | 4 | Additionally, we waive copyright and related rights in the work 5 | worldwide through the CC0 1.0 Universal public domain dedication. 6 | 7 | ## CC0 1.0 Universal Summary 8 | 9 | This is a human-readable summary of the [Legal Code (read the full text)](https://creativecommons.org/publicdomain/zero/1.0/legalcode). 10 | 11 | ### No Copyright 12 | 13 | The person who associated a work with this deed has dedicated the work to 14 | the public domain by waiving all of his or her rights to the work worldwide 15 | under copyright law, including all related and neighboring rights, to the 16 | extent allowed by law. 17 | 18 | You can copy, modify, distribute and perform the work, even for commercial 19 | purposes, all without asking permission. 20 | 21 | ### Other Information 22 | 23 | In no way are the patent or trademark rights of any person affected by CC0, 24 | nor are the rights that other persons may have in the work or in how the 25 | work is used, such as publicity or privacy rights. 26 | 27 | Unless expressly stated otherwise, the person who associated a work with 28 | this deed makes no warranties about the work, and disclaims liability for 29 | all uses of the work, to the fullest extent permitted by applicable law. 30 | When using or citing the work, you should not imply endorsement by the 31 | author or the affirmer. 32 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | run: 2 | make -j2 serve watch-css 3 | 4 | serve: 5 | bundle exec jekyll serve --host 0.0.0.0 --incremental 6 | 7 | watch-css: 8 | npm run watch:css 9 | 10 | clean: 11 | rm -rf _site 12 | 13 | test: build 14 | bundle exec rspec spec 15 | node --test spec/e2e/** 16 | 17 | test-a11y: 18 | node --test spec/e2e/accessibility.test.js 19 | 20 | htmlproofer: 21 | bundle exec scripts/htmlproofer 22 | 23 | build-site: 24 | bundle exec jekyll build 25 | 26 | build-css: 27 | npm run build:css 28 | 29 | build: build-site build-css 30 | 31 | install-dependencies: bundle npm 32 | 33 | lint-js: 34 | npm run lint 35 | 36 | npm: 37 | npm ci 38 | 39 | bundle: 40 | bundle check || bundle install 41 | 42 | setup: install-dependencies 43 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Login.gov Dev Docs 2 | 3 | [View it live ❯](https://developers.login.gov/) 4 | 5 | ## Temporary Alert 6 | 7 | To add a temporary alert to the developer docs set the `temporary_alert` configuration value in `_config.yml` to a string with the desired alert contents, e.g. `The sandbox will be unavailable from 5:30-6:30p ET on Tuesday, August 9th.`. To turn off the alert change the configuration value to `false`. 8 | 9 | ## Development 10 | 11 | ### Locally 12 | 13 | Run initial setup: 14 | 15 | ```sh 16 | make setup 17 | ``` 18 | 19 | Run the server locally: 20 | 21 | ```sh 22 | make run 23 | ``` 24 | 25 | Run the tests: 26 | 27 | ```sh 28 | make test 29 | ``` 30 | 31 | This site uses the anchor.js. To update it: 32 | 33 | - Download latest [anchor.js](https://github.com/bryanbraun/anchorjs) and put in `assets/js/` 34 | 35 | #### YAML files 36 | 37 | When updating a `yml` file, you only need to update the version in the `/assets` directory. This is symlinked to the `_includes` directory. 38 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | As a U.S. Government agency, the General Services Administration (GSA) takes 4 | seriously our responsibility to protect the public's information, including 5 | financial and personal information, from unwarranted disclosure. 6 | 7 | ## Reporting a Vulnerability 8 | 9 | Services operated by the U.S. General Services Administration (GSA) 10 | are covered by the **GSA Vulnerability Disclosure Program (VDP)**. 11 | 12 | See the [GSA Vulnerability Disclosure Policy](https://gsa.gov/vulnerability-disclosure-policy) 13 | at for details including: 14 | 15 | * How to submit a report if you believe you have discovered a vulnerability. 16 | * GSA's coordinated disclosure policy. 17 | * Information on how you may conduct security research on GSA developed 18 | software and systems. 19 | * Important legal and policy guidance. 20 | 21 | ### [Bug Bounties](https://hackerone.com/gsa_bbp) 22 | 23 | Certain GSA/TTS programs have bug bounties that are not discussed at the above link. If you find security issues for any of the following domains: 24 | 25 | * cloud.gov 26 | * search.gov 27 | * usa.gov 28 | * 18f.gov 29 | * fedramp.gov 30 | * login.gov 31 | * vote.gov 32 | 33 | you should also review the [GSA Bug Bounty program](https://hackerone.com/gsa_bbp) at for a potential bounty. 34 | 35 | ## Supported Versions 36 | 37 | Please note that only certain branches are supported with security updates. 38 | 39 | | Version (Branch) | Supported | 40 | | ---------------- | ------------------ | 41 | | main | :white_check_mark: | 42 | | other | :x: | 43 | 44 | When using this code or reporting vulnerabilities please only use supported 45 | versions. 46 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | # Site settings 2 | title: Login.gov 3 | description: Welcome to the Login.gov developer documentation! 4 | github_repo_url: https://github.com/GSA-TTS/identity-dev-docs # enables "edit this page" button 5 | url: https://developers.login.gov 6 | 7 | # temporary_alert: "The Login.gov sandbox (not production) will be unavailable from 5-6p ET on Tuesday, January 31st, 2023 for maintenance." 8 | temporary_alert: false 9 | 10 | # GSA Office of Strategic Communication (OSC) Google Analytics 11 | osc_analytics_ga_measurement_id: null 12 | 13 | plugins: 14 | - jekyll-redirect-from 15 | - jekyll-sitemap 16 | 17 | copy_to_destination: 18 | - node_modules/@18f/identity-design-system/dist/assets 19 | 20 | # Pages 21 | collections: 22 | pages: 23 | output: true 24 | permalink: /:path/ 25 | 26 | # Build settings 27 | kramdown: 28 | hard_wrap: true 29 | syntax_highlighter: rouge 30 | syntax_highlighter_opts: 31 | formatter: HTMLLegacyA11y 32 | 33 | sass: 34 | load_paths: 35 | - node_modules 36 | 37 | exclude: 38 | - README.md 39 | - CONTRIBUTING.md 40 | - Makefile 41 | - package.json 42 | - package-lock.json 43 | # default excludes from https://github.com/jekyll/jekyll/blob/493b800edbf6f6e97c34d1812698260907255665/lib/site_template/_config.yml#L45 44 | - .sass-cache/ 45 | - .jekyll-cache/ 46 | - assets/scss 47 | - gemfiles/ 48 | - Gemfile 49 | - Gemfile.lock 50 | - node_modules/ 51 | - vendor/bundle/ 52 | - vendor/cache/ 53 | - vendor/gems/ 54 | - vendor/ruby/ 55 | 56 | keep_files: 57 | - assets/css 58 | 59 | # Defaults 60 | defaults: 61 | - scope: 62 | path: '' 63 | values: 64 | layout: documentation 65 | 66 | excerpt_separator: 67 | -------------------------------------------------------------------------------- /_data/nav.yml: -------------------------------------------------------------------------------- 1 | primary: 2 | - text: Get Started 3 | href: / 4 | - text: Integration 5 | href: /overview/ 6 | - text: OpenID Connect 7 | href: /oidc/getting-started/ 8 | - text: SAML 9 | href: /saml/getting-started/ 10 | - text: Attributes 11 | href: /attributes/ 12 | - text: User Experience 13 | href: /user-experience/getting-started/ 14 | - text: Testing 15 | href: /testing/ 16 | - text: Production 17 | href: /production/ 18 | - text: Security 19 | href: /security-events/ 20 | - text: Support 21 | href: /support/ 22 | footer_sections: 23 | - heading: For agencies 24 | links: 25 | - label: Become a Partner 26 | url: '$BASE_URL/partners/' 27 | - label: Developer Guide 28 | url: '/' 29 | - heading: Learn 30 | links: 31 | - label: About us 32 | url: '$BASE_URL/about-us/' 33 | - label: Accessibility 34 | url: '$BASE_URL/accessibility/' 35 | - label: Join us 36 | url: '$BASE_URL/join/' 37 | - label: Privacy & Security 38 | url: '$BASE_URL/policy/' 39 | - heading: Support 40 | links: 41 | - label: Contact us 42 | url: '$BASE_URL/contact/' 43 | - label: Help Center 44 | url: '$BASE_URL/help/' 45 | -------------------------------------------------------------------------------- /_data/risc_incoming.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Incoming Events 3 | # 4 | - friendly_name: Authorization Fraud Detected 5 | direction: incoming 6 | event_type: https://schemas.login.gov/secevent/risc/event-type/authorization-fraud-detected 7 | description: > 8 | RPs should submit this event when they believe a user's credentials have been compromised, 9 | that somebody who is not the user was able to sign in to a user's account. Login.gov may force 10 | reset of the user's password when we receive this event. 11 | 12 | - friendly_name: Identity Fraud Detected 13 | direction: incoming 14 | event_type: https://schemas.login.gov/secevent/risc/event-type/identity-fraud-detected 15 | description: > 16 | RPs should submit this event when they suspect an account has been used to commit identity theft or related fraudulent activity. Login.gov may reset the user's profile and verified attributes data when we receive this event. 17 | 18 | -------------------------------------------------------------------------------- /_data/risc_outgoing.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Outgoing Events 3 | # 4 | - friendly_name: Account Purged 5 | direction: outgoing 6 | event_type: https://schemas.openid.net/secevent/risc/event-type/account-purged 7 | spec_url: "https://openid.net/specs/openid-risc-event-types-1_0-ID1.html#rfc.section.2.2" 8 | description: > 9 | Login.gov pushes this event when a user deletes their account. 10 | payload_schema: &iss_sub_schema 11 | - key: subject 12 | description: An event will include a **subject** object, with the following keys 13 | properties: 14 | - key: subject_type 15 | type: string 16 | description: > 17 | Will be **iss-sub**, this indicates the **sub** is the subject provided by the original issuer (Login.gov) 18 | - key: iss 19 | type: string 20 | description: > 21 | This is Login.gov's issuer, the root URL for Login.gov. In the agency integration environment, this is `https://idp.int.identitysandbox.gov` 22 | - key: sub 23 | type: string 24 | description: > 25 | The UUID identifying the user. This is the same as the `sub` inside the `id_token` JWT in the OpenID Token endpoint. 26 | example_payload: { 27 | "https://schemas.openid.net/secevent/risc/event-type/account-purged": { 28 | "subject": { 29 | "subject_type": "iss-sub", 30 | "iss": "https://idp.int.identitysandbox.gov", 31 | "sub": "<$SUB>" 32 | } 33 | } 34 | } 35 | 36 | - friendly_name: Account Disabled 37 | direction: outgoing 38 | event_type: https://schemas.openid.net/secevent/risc/event-type/account-disabled 39 | spec_url: "https://openid.net/specs/openid-risc-event-types-1_0-ID1.html#account-disabled" 40 | description: > 41 | Login.gov pushes this event when a user account suspended. 42 | payload_schema: 43 | - key: subject 44 | description: An event will include a **subject** object, with the following keys 45 | properties: 46 | - key: subject_type 47 | type: string 48 | description: > 49 | Will be **iss-sub**, this indicates the **sub** is the subject provided by the original issuer (Login.gov) 50 | - key: iss 51 | type: string 52 | description: > 53 | This is Login.gov's issuer, the root URL for Login.gov. In the agency integration environment, this is `https://idp.int.identitysandbox.gov` 54 | - key: sub 55 | type: string 56 | description: > 57 | The UUID identifying the user. This is the same as the `sub` inside the `id_token` JWT in the OpenID Token endpoint. 58 | - key: reason 59 | type: string 60 | description: > 61 | Optional, describes why was the account disabled. 62 | example_payload: { 63 | "https://schemas.openid.net/secevent/risc/event-type/account-disabled": { 64 | "subject": { 65 | "subject_type": "iss-sub", 66 | "iss": "https://idp.int.identitysandbox.gov", 67 | "sub": "<$SUB>" 68 | }, 69 | "reason": "account-suspension", 70 | } 71 | } 72 | 73 | - friendly_name: Account Enabled 74 | direction: outgoing 75 | event_type: https://schemas.openid.net/secevent/risc/event-type/account-enabled 76 | spec_url: "https://openid.net/specs/openid-risc-event-types-1_0-ID1.html#account-enabled" 77 | description: > 78 | Login.gov pushes this event when a user account reinstated. 79 | payload_schema: 80 | - key: subject 81 | description: An event will include a **subject** object, with the following keys 82 | properties: 83 | - key: subject_type 84 | type: string 85 | description: > 86 | Will be **iss-sub**, this indicates the **sub** is the subject provided by the original issuer (Login.gov) 87 | - key: iss 88 | type: string 89 | description: > 90 | This is Login.gov's issuer, the root URL for Login.gov. In the agency integration environment, this is `https://idp.int.identitysandbox.gov` 91 | - key: sub 92 | type: string 93 | description: > 94 | The UUID identifying the user. This is the same as the `sub` inside the `id_token` JWT in the OpenID Token endpoint. 95 | example_payload: { 96 | "https://schemas.openid.net/secevent/risc/event-type/account-enabled": { 97 | "subject": { 98 | "subject_type": "iss-sub", 99 | "iss": "https://idp.int.identitysandbox.gov", 100 | "sub": "<$SUB>" 101 | } 102 | } 103 | } 104 | 105 | - friendly_name: Identifier Recycled 106 | direction: outgoing 107 | event_type: https://schemas.openid.net/secevent/risc/event-type/identifier-recycled 108 | spec_url: "https://openid.net/specs/openid-risc-event-types-1_0-ID1.html#rfc.section.2.6" 109 | description: > 110 | Login.gov pushes this event when a user removes an email address from their account, freeing up the email address as an identifier. 111 | payload_schema: &email_schema 112 | - key: subject 113 | description: An event will include a **subject** object, with the following keys 114 | properties: 115 | - key: subject_type 116 | type: string 117 | description: > 118 | Will be **email** 119 | - key: email 120 | type: string 121 | description: > 122 | This is the email address that no longer belongs to any user. 123 | example_payload: { 124 | "https://schemas.openid.net/secevent/risc/event-type/identifier-recycled": { 125 | "subject": { 126 | "subject_type": "email", 127 | "email": "<$EMAIL>" 128 | } 129 | } 130 | } 131 | 132 | - friendly_name: Identifier Changed 133 | direction: outgoing 134 | event_type: https://schemas.openid.net/secevent/risc/event-type/identifier-changed 135 | spec_url: "https://openid.net/specs/openid-risc-event-types-1_0-ID1.html#rfc.section.2.5" 136 | description: > 137 | Login.gov pushes this event when a user changes the email address associated with their account. 138 | payload_schema: 139 | *email_schema 140 | example_payload: { 141 | "https://schemas.openid.net/secevent/risc/event-type/identifier-changed": { 142 | "subject": { 143 | "subject_type": "email", 144 | "email": "<$EMAIL>" 145 | } 146 | } 147 | } 148 | 149 | - friendly_name: Account Locked Due to MFA (Multi-Factor Authentication) Limit Reached 150 | event_type: https://schemas.login.gov/secevent/risc/event-type/mfa-limit-account-locked 151 | spec_url: 152 | description: > 153 | Login.gov pushes this event when a user fails MFA with their 154 | second factor enough times to hit the rate limit, and is subsequently locked out of their 155 | account for a period of time. 156 | payload_schema: 157 | *iss_sub_schema 158 | example_payload: { 159 | "https://schemas.login.gov/secevent/risc/event-type/mfa-limit-account-locked": { 160 | "subject": { 161 | "subject_type": "iss-sub", 162 | "iss": "https://idp.int.identitysandbox.gov", 163 | "sub": "<$SUB>" 164 | } 165 | } 166 | } 167 | 168 | - friendly_name: Recovery Activated 169 | event_type: https://schemas.openid.net/secevent/risc/event-type/recovery-activated 170 | spec_url: "https://openid.net/specs/openid-risc-event-types-1_0-ID1.html#rfc.section.2.8" 171 | description: > 172 | Login.gov pushes this event when a user starts the "Forgot Password" flow for an account. 173 | payload_schema: 174 | *iss_sub_schema 175 | example_payload: { 176 | "https://schemas.openid.net/secevent/risc/event-type/recovery-activated": { 177 | "subject": { 178 | "subject_type": "iss-sub", 179 | "iss": "https://idp.int.identitysandbox.gov", 180 | "sub": "<$SUB>" 181 | } 182 | } 183 | } 184 | 185 | - friendly_name: Password Reset 186 | event_type: https://schemas.login.gov/secevent/risc/event-type/password-reset 187 | description: > 188 | Login.gov pushes this event when a user completes a password reset, either as part of account recovery 189 | or intentionally through the account page. 190 | payload_schema: 191 | *iss_sub_schema 192 | example_payload: { 193 | "https://schemas.login.gov/secevent/risc/event-type/password-reset": { 194 | "subject": { 195 | "subject_type": "iss-sub", 196 | "iss": "https://idp.int.identitysandbox.gov", 197 | "sub": "<$SUB>" 198 | } 199 | } 200 | } 201 | 202 | - friendly_name: Recovery Information Changed 203 | event_type: https://schemas.openid.net/secevent/risc/event-type/recovery-information-changed 204 | spec_url: "https://openid.net/specs/openid-risc-event-types-1_0-ID1.html#rfc.section.2.9" 205 | description: > 206 | Login.gov pushes this event when a user changes any of their second factor authentication methods, 207 | for example, adding or removing an email, phone address, TOTP authentication app, backup codes, 208 | or PIV/CAC. 209 | payload_schema: 210 | *iss_sub_schema 211 | example_payload: { 212 | "https://schemas.openid.net/secevent/risc/event-type/recovery-information-changed": { 213 | "subject": { 214 | "subject_type": "iss-sub", 215 | "iss": "https://idp.int.identitysandbox.gov", 216 | "sub": "<$SUB>" 217 | } 218 | } 219 | } 220 | 221 | - friendly_name: Reproofing Completed 222 | event_type: https://schemas.login.gov/secevent/risc/event-type/reproof-completed 223 | spec_url: 224 | description: > 225 | Login.gov pushes this event when a user re-verifies their identity (with the identity 226 | proofing process). This event is only sent if they previously had an active verified profile, 227 | not for the first-time identity verification. 228 | payload_schema: 229 | *iss_sub_schema 230 | example_payload: { 231 | "https://schemas.login.gov/secevent/risc/event-type/mfa-limit-account-locked": { 232 | "subject": { 233 | "subject_type": "iss-sub", 234 | "iss": "https://idp.int.identitysandbox.gov", 235 | "sub": "<$SUB>" 236 | } 237 | } 238 | } 239 | -------------------------------------------------------------------------------- /_data/saml.yml: -------------------------------------------------------------------------------- 1 | year: 2 | current: 2025 3 | previous: 2024 4 | certs: 5 | sandbox: | 6 | -----BEGIN CERTIFICATE----- 7 | MIID7TCCAtWgAwIBAgIUL13CinhNFLIW8m6AsLvcPXP9TUgwDQYJKoZIhvcNAQEL 8 | BQAwgYUxCzAJBgNVBAYTAlVTMR0wGwYDVQQIDBREaXN0cmljdCBvZiBDb2x1bWJp 9 | YTETMBEGA1UEBwwKV2FzaGluZ3RvbjEMMAoGA1UECgwDR1NBMRIwEAYDVQQLDAlM 10 | b2dpbi5nb3YxIDAeBgNVBAMMF2ludC5pZGVudGl0eXNhbmRib3guZ292MB4XDTI1 11 | MDExMzIwMDAzNVoXDTI2MDQwMTIwMDAzNVowgYUxCzAJBgNVBAYTAlVTMR0wGwYD 12 | VQQIDBREaXN0cmljdCBvZiBDb2x1bWJpYTETMBEGA1UEBwwKV2FzaGluZ3RvbjEM 13 | MAoGA1UECgwDR1NBMRIwEAYDVQQLDAlMb2dpbi5nb3YxIDAeBgNVBAMMF2ludC5p 14 | ZGVudGl0eXNhbmRib3guZ292MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC 15 | AQEAvDe5rImG+Al9Uq5b7OgJbce8OelJWK3HhAiDU1PdT9IiKHfsmZYZQi6vclU7 16 | 92/yVGQWUuEn4J1Inndb10LujR/8eaNlgA8QaYylh+SYJ1yfc5uUfKDP7dPkLAL4 17 | s8EC/hX9jygyFS9w1Ur0BEAyy6vGXaINnpQICYgdzZDO91do4APyuPRxbNNvmvr1 18 | /5PPf6/2Ch4BZBqLu4pmdYIyv8Nhl0TbAepRXY4K5ZXJdM0IkUQthzinJqypXVYh 19 | 8ePG9bUfKWHW9FRq8vpmiWO6oCi34IIeMb0taWDdSuVBvjlfHJ9RMQH+j6nrNU6e 20 | t4vofbUc746lze5l4FzeAbxwXwIDAQABo1MwUTAdBgNVHQ4EFgQU/w7Uv8hJzTIm 21 | FXNOhrRQq8XdlTgwHwYDVR0jBBgwFoAU/w7Uv8hJzTImFXNOhrRQq8XdlTgwDwYD 22 | VR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAivHaNV1KhennEVDSAmV3 23 | a/WEV/ptWTCQoc06hhgLRibkkj9ryWUqagSQhlGSwe2tyOodfGwq/Kk9BQ3NS+zb 24 | qPeq4GzxVedtwOwTu4p3SzUKWALKZI4vASPEVuBXc/z6LW8fyCZ4OFPV9FtoFAI4 25 | SXnZv3VZzjEHtfVOVSTUKP8UIdwDQy+W7X365ZWY6625++ye9CuWEmLisOKhb9Ht 26 | L0ZzbyyDWunTeUlDVlhyCFyGNzuTDuCEOqPXxCiwGfJE4huVmxMG8kSAeS1y0Egr 27 | EOvHgHteQTmjxZ/Za36xmO5M67//Y+wOsgQSGgYxPEK4qRxKK2Aw+C6ViHwasfHG 28 | ow== 29 | -----END CERTIFICATE----- 30 | production: | 31 | -----BEGIN CERTIFICATE----- 32 | MIIDzzCCAregAwIBAgIUBuxTXQhYd7UzOhO11pnNri8E5zswDQYJKoZIhvcNAQEL 33 | BQAwdzELMAkGA1UEBhMCVVMxHTAbBgNVBAgMFERpc3RyaWN0IG9mIENvbHVtYmlh 34 | MRMwEQYDVQQHDApXYXNoaW5ndG9uMQwwCgYDVQQKDANHU0ExEjAQBgNVBAsMCUxv 35 | Z2luLmdvdjESMBAGA1UEAwwJbG9naW4uZ292MB4XDTI1MDExMzIwMDEzM1oXDTI2 36 | MDQwMTIwMDEzM1owdzELMAkGA1UEBhMCVVMxHTAbBgNVBAgMFERpc3RyaWN0IG9m 37 | IENvbHVtYmlhMRMwEQYDVQQHDApXYXNoaW5ndG9uMQwwCgYDVQQKDANHU0ExEjAQ 38 | BgNVBAsMCUxvZ2luLmdvdjESMBAGA1UEAwwJbG9naW4uZ292MIIBIjANBgkqhkiG 39 | 9w0BAQEFAAOCAQ8AMIIBCgKCAQEAq1mNLPlOoszuVQhW0yJKNWI7XEg776vmeaRr 40 | zGMLmenaV2tXanozBxoehNmwC7egpSCoq5PfnzQGRhZqGAsbi1FVqLmEgOlEMgKG 41 | HQ3oOoeNf7wmouOsjLIFu76nGIbXAknnmgveki6tfU1czpgpOwoOb6JLk6VMOaA1 42 | x7eBVfoZlPg9jjM9KpyYVB7l8kmEzk6SUEP6LUXfcfSb97K5XTw06V/L2hyTBR2C 43 | MCKC1iuA9O/DReVRYSkt1IZwpzW5nTGkzyboH3crjKCpHlVOCoJFcQwnxaTrFNv7 44 | rXbnmwqsypWk9LCLQeqmlfnwlXWFGU17hBHIqvsS6Yo3y3JVBQIDAQABo1MwUTAd 45 | BgNVHQ4EFgQUyT7sOy64K5nT+cct7JHQF0gMN4cwHwYDVR0jBBgwFoAUyT7sOy64 46 | K5nT+cct7JHQF0gMN4cwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOC 47 | AQEALfe6JZuKCQSdV75bDhHecnLmqLhhhYoHVoDhqWpA1vX7fyz20Qp0pFog+G65 48 | RZGnaBWNxCJB4s7/E7RjVNC0RAUR3Vojd6nD8kOPHXDR4IamURTfIAaEnNFNFPGM 49 | gR6iQEptHyjs+d0gubKUyqvKQR6WibQsgzSo6d2IsYFFAzlhQeCm3XeK31z97k9q 50 | 9mUm1AM2mlhs4qTBWnBE1xeDOuG05FS/fTLQWujprrQXbEq40jrBfVKmLSCxq2Sh 51 | eCvbFvvY60cXYC4VSjdWHaFuIJVeNAlKugMsDxigJzlU7IgF2dI/vHtS8H6Job/Z 52 | LfgJGSqarlSYFHq3B4IjMqigTQ== 53 | -----END CERTIFICATE----- 54 | -------------------------------------------------------------------------------- /_includes/accordion.html: -------------------------------------------------------------------------------- 1 | {% comment %} 2 | include 3 | - content 4 | - accordion_id 5 | - title 6 | - id 7 | {% endcomment %} 8 |
9 | 16 |
17 |
18 | {{ include.content | markdownify }} 19 |
20 | -------------------------------------------------------------------------------- /_includes/alert.html: -------------------------------------------------------------------------------- 1 | {% comment %} 2 | include 3 | - content 4 | - alert_class (optional) 5 | {% endcomment %} 6 |
7 |
8 |

9 | {{ include.content }} 10 |

11 |
12 |
13 | -------------------------------------------------------------------------------- /_includes/dap.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /_includes/footer-navigation.html: -------------------------------------------------------------------------------- 1 | 37 | -------------------------------------------------------------------------------- /_includes/footer.html: -------------------------------------------------------------------------------- 1 | 80 | 81 | -------------------------------------------------------------------------------- /_includes/icon.html: -------------------------------------------------------------------------------- 1 | {% comment %} 2 | include 3 | - style 4 | - icon_name 5 | {% endcomment %} 6 |
7 | 10 |
11 | -------------------------------------------------------------------------------- /_includes/icon_list.html: -------------------------------------------------------------------------------- 1 | {% comment %} 2 | include 3 | - style 4 | - icon_name 5 | - content 6 | {% endcomment %} 7 | 8 | {% capture full_style %} 9 | {{include.style}} usa-icon-list__icon 10 | {% endcapture %} 11 | 12 | {% include icon.html style=full_style icon_name=include.icon_name %} 13 |
14 | {{ include.content | markdownify }} 15 |
16 | -------------------------------------------------------------------------------- /_includes/nav/item.html: -------------------------------------------------------------------------------- 1 | {% if include.link.href == page.url -%} 2 | {% assign is_current_page = true -%} 3 | {% else -%} 4 | {% assign is_current_page = false -%} 5 | {% endif -%} 6 | {% assign first_character = include.link.href | slice: 0 -%} 7 | {% if first_character == '#' -%} 8 | {% assign href = include.link.href -%} 9 | {% else -%} 10 | {% assign href = include.link.href | relative_url -%} 11 | {% endif -%} 12 | 13 | 14 | {{ include.link.text | smartify }} 15 | 16 | 17 | {% if include.link.links -%} 18 | 25 | {% endif -%} 26 | 27 | {% if is_current_page %} 28 | 35 | {% endif %} 36 | -------------------------------------------------------------------------------- /_includes/nav/list.html: -------------------------------------------------------------------------------- 1 | {% for link in include.links -%} 2 |
  • 3 | {% include nav/item.html 4 | link = link 5 | li_class = include.li_class 6 | ul_class = include.ul_class 7 | subnav_ul_class = include.subnav_ul_class 8 | %} 9 |
  • 10 | {% endfor %} 11 | -------------------------------------------------------------------------------- /_includes/osc_analytics.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | -------------------------------------------------------------------------------- /_includes/risc_event.json: -------------------------------------------------------------------------------- 1 | {% comment %} 2 | Include: 3 | - event 4 | - direction (incoming/outgoing) 5 | {% endcomment %} 6 | { 7 | "friendly_name": {{ include.event.friendly_name | jsonify }}, 8 | "event_type": {{ include.event.event_type | jsonify}}, 9 | "direction": {{ include.direction | jsonify }}, 10 | {% if include.event.spec_url %} 11 | "spec_url": {{ include.event.spec_url | jsonify }}, 12 | {% endif %} 13 | "description": {{ include.event.description | strip | jsonify }} 14 | } 15 | -------------------------------------------------------------------------------- /_includes/schema.html: -------------------------------------------------------------------------------- 1 | {% comment %} 2 | Includes: 3 | - schema, array of: 4 | - key 5 | - description 6 | - type (optional) 7 | - properties (optional) 8 | {% endcomment %} 9 | -------------------------------------------------------------------------------- /_includes/search.html: -------------------------------------------------------------------------------- 1 | 2 | 30 | -------------------------------------------------------------------------------- /_includes/snippets/auth_content/aal_values.md: -------------------------------------------------------------------------------- 1 | {% capture aal_values %} 2 | We default to requiring a user to be authenticated with a second factor: 3 | - **`urn:gov:gsa:ac:classes:sp:PasswordProtectedTransport:duo`** 4 | This specifies that a user has been authenticated with a second factor. This value will be returned in the user attributes by default. We do not allow strict AAL1, because it implies that a user did not authenticate with a second factor. This setting requires users to reauthenticate with a separate second factor (i.e. not a remembered device) once every 30 days at a minimum. 5 | 6 | Stricter behavior can be specified by adding one of: 7 | 8 | - **`http://idmanagement.gov/ns/assurance/aal/2`** 9 | This is the same as the default behavior except users must authenticate with a separate second factor (i.e. not a remembered device). 10 | - **`http://idmanagement.gov/ns/assurance/aal/2?phishing_resistant=true`** 11 | This specifies that a user has been authenticated with a crytographically secure method, such as WebAuthn or using a PIV/CAC. Users must _always_ authenticate with a second factor. 12 | - **`http://idmanagement.gov/ns/assurance/aal/2?hspd12=true`** 13 | This specifies that a user has been authenticated with an HSPD12 credential (requires PIV/CAC). Users must _always_ authenticate with a second factor. 14 | {% endcapture %} 15 |
    16 | {{ aal_values | markdownify }} 17 |
    18 | -------------------------------------------------------------------------------- /_includes/snippets/auth_content/deprecated_values.md: -------------------------------------------------------------------------------- 1 | {% capture deprecated_values %} 2 | These are not recommended, and only for legacy compatibility. 3 | - **`http://idmanagement.gov/ns/assurance/ial/1`** 4 | Requires basic identity assurance, does not require identity verification. Equivalent to `urn:acr.login.gov:auth-only`. 5 | - **`http://idmanagement.gov/ns/assurance/ial/2`** 6 | Requires that the user has gone through basic identity verification. Equivalent to `urn:acr.login.gov:verified`. 7 | 8 | Does not meet NIST 800-63-3 IAL2 standard. 9 | - **`http://idmanagement.gov/ns/assurance/loa/1`** 10 | Equivalent to `urn:acr.login.gov:auth-only`. 11 | 12 | - **`http://idmanagement.gov/ns/assurance/loa/3`** 13 | Equivalent to `urn:acr.login.gov:verified`. 14 | {% endcapture %} 15 |
    16 | {{ deprecated_values | markdownify }} 17 |
    -------------------------------------------------------------------------------- /_includes/snippets/auth_content/service_levels.md: -------------------------------------------------------------------------------- 1 | {% capture type_of_service %} 2 | A type of service level must be specified. 3 | - **`urn:acr.login.gov:auth-only`** 4 | Requires basic identity assurance: email address, password, and at least one MFA method. No identity verification. 5 | 6 | Meets either NIST 800-63-3 AAL1 or AAL2 standard (depending on agency integration configuration) 7 | - **`urn:acr.login.gov:verified`** 8 | Requires that the user has gone through basic identity verification without facial matching. 9 | 10 | Does not meet NIST 800-63-3 IAL2 standard. 11 | - **`urn:acr.login.gov:verified-facial-match-required`** 12 | Requires identity verification with facial match for **all** users. Even if a user has been previously verified without facial matching, they will be required to go through verification with facial match. 13 | 14 | Meets NIST 800-63-3 IAL2 standard. 15 | - **`urn:acr.login.gov:verified-facial-match-preferred`** 16 | Requires identity verification. Users with no previous identity verification will be required to go through a facial match. Users with previous identity verification will use that data, even if it was done without facial match. 17 | 18 | Authentications for users who verify with facial matching will meet NIST 800-63-3 IAL2 standard. Authentication for users who do not do facial matching will not meet NIST 800-63-3 IAL2 standard. 19 | {% endcapture %} 20 |
    21 | {{ type_of_service | markdownify }} 22 |
    23 | -------------------------------------------------------------------------------- /_includes/snippets/oidc/auth/failure.md: -------------------------------------------------------------------------------- 1 | {% capture fail_response %} 2 | ```bash 3 | https://agency.gov/response? 4 | error=access_denied& 5 | state=abcdefghijklmnopabcdefghijklmnop 6 | ``` 7 | {% endcapture %} 8 | 9 |
    10 | {{ fail_response | markdownify }} 11 |
    -------------------------------------------------------------------------------- /_includes/snippets/oidc/auth/jwt.md: -------------------------------------------------------------------------------- 1 | {% capture code %} 2 | ```bash 3 | https://idp.int.identitysandbox.gov/openid_connect/authorize? 4 | acr_values=urn:acr.login.gov:auth-only& 5 | client_id=${CLIENT_ID}& 6 | nonce=${NONCE}& 7 | prompt=select_account& 8 | redirect_uri=${REDIRECT_URI}& 9 | response_type=code& 10 | scope=openid+email& 11 | state=abcdefghijklmnopabcdefghijklmnop 12 | ``` 13 | {% endcapture %} 14 | 15 | 16 |
    17 | {{ code | markdownify }} 18 |
    19 | -------------------------------------------------------------------------------- /_includes/snippets/oidc/auth/pkce.md: -------------------------------------------------------------------------------- 1 | {% capture pkce %} 2 | ```bash 3 | https://idp.int.identitysandbox.gov/openid_connect/authorize? 4 | acr_values=urn:acr.login.gov:auth-only& 5 | client_id=${CLIENT_ID}& 6 | code_challenge=${CODE_CHALLENGE}& 7 | code_challenge_method=S256& 8 | nonce=${NONCE}& 9 | prompt=select_account& 10 | redirect_uri=${REDIRECT_URI}& 11 | response_type=code& 12 | scope=openid+email& 13 | state=abcdefghijklmnopabcdefghijklmnop 14 | ``` 15 | {% endcapture %} 16 | 17 | 18 |
    19 | {{ pkce | markdownify }} 20 |
    21 | -------------------------------------------------------------------------------- /_includes/snippets/oidc/auth/success.md: -------------------------------------------------------------------------------- 1 | {% capture success_response %} 2 | ```bash 3 | https://agency.gov/response? 4 | code=12345& 5 | state=abcdefghijklmnopabcdefghijklmnop 6 | ``` 7 | {% endcapture %} 8 | 9 |
    10 | {{ success_response | markdownify }} 11 |
    -------------------------------------------------------------------------------- /_includes/snippets/oidc/certificates.md: -------------------------------------------------------------------------------- 1 | {% capture ssl %} 2 | ``` 3 | openssl req -nodes -x509 -days 365 -newkey rsa:2048 -keyout private.pem -out public.crt 4 | ``` 5 | {% endcapture %} 6 |
    7 | {{ ssl | markdownify }} 8 |
    9 | -------------------------------------------------------------------------------- /_includes/snippets/oidc/logout/request.md: -------------------------------------------------------------------------------- 1 | {% capture code %} 2 | ```bash 3 | https://idp.int.identitysandbox.gov/openid_connect/logout? 4 | client_id=${CLIENT_ID}& 5 | post_logout_redirect_uri=${REDIRECT_URI}& 6 | state=abcdefghijklmnopabcdefghijklmnop 7 | ``` 8 | {% endcapture %} 9 | 10 |
    11 | {{ code | markdownify }} 12 |
    -------------------------------------------------------------------------------- /_includes/snippets/oidc/logout/response.md: -------------------------------------------------------------------------------- 1 | {% capture code %} 2 | ```bash 3 | https://agency.gov/response? 4 | state=abcdefghijklmnopabcdefghijklmnop 5 | ``` 6 | {% endcapture %} 7 | 8 |
    9 | {{ code | markdownify }} 10 |
    -------------------------------------------------------------------------------- /_includes/snippets/oidc/token/jwt.md: -------------------------------------------------------------------------------- 1 | {% capture private_key_jwt %} 2 | ```bash 3 | POST https://idp.int.identitysandbox.gov/api/openid_connect/token 4 | 5 | client_assertion=${CLIENT_ASSERTION}& 6 | client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer& 7 | code=${CODE}& 8 | grant_type=authorization_code 9 | ``` 10 | {% endcapture %} 11 |
    12 | {{ private_key_jwt | markdownify }} 13 |
    -------------------------------------------------------------------------------- /_includes/snippets/oidc/token/pkce.md: -------------------------------------------------------------------------------- 1 | {% capture code %} 2 | ```bash 3 | POST https://idp.int.identitysandbox.gov/api/openid_connect/token 4 | 5 | code=${CODE}& 6 | code_verifier=${CODE_VERIFIER}& 7 | grant_type=authorization_code 8 | ``` 9 | {% endcapture %} 10 |
    11 | {{ code | markdownify }} 12 |
    -------------------------------------------------------------------------------- /_includes/snippets/oidc/token/response.md: -------------------------------------------------------------------------------- 1 | {% capture code %} 2 | ```json 3 | { 4 | "access_token": "hhJES3wcgjI55jzjBvZpNQ", 5 | "token_type": "Bearer", 6 | "expires_in": 3600, 7 | "id_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJiMmQyZDExNS0xZDdlLTQ1NzktYjlkNi1mOGU4NGY0ZjU2Y2EiLCJpc3MiOiJodHRwczovL2lkcC5pbnQubG9naW4uZ292IiwiYWNyIjoiaHR0cDovL2lkbWFuYWdlbWVudC5nb3YvbnMvYXNzdXJhbmNlL2xvYS8xIiwibm9uY2UiOiJhYWQwYWE" 8 | } 9 | ``` 10 | {% endcapture %} 11 |
    12 | {{ code | markdownify }} 13 |
    -------------------------------------------------------------------------------- /_includes/snippets/oidc/token/token.md: -------------------------------------------------------------------------------- 1 | {% capture code %} 2 | ```json 3 | { 4 | "sub": "b2d2d115-1d7e-4579-b9d6-f8e84f4f56ca", 5 | "iss": "https://idp.int.identitysandbox.gov", 6 | "acr": "urn:acr.login.gov:auth-only", 7 | "nonce": "aad0aa969c156b2dfa685f885fac7083", 8 | "aud": "urn:gov:gsa:openidconnect:development", 9 | "jti": "jC7NnU8dNNV5lisQBm1jtA", 10 | "at_hash": "tlNbiqr1Lr2YcNRGjzwlIg", 11 | "c_hash": "hXjq7kOrtQK_za_6tONxcw", 12 | "exp": 1489694196, 13 | "iat": 1489694198, 14 | "nbf": 1489694198 15 | } 16 | ``` 17 | {% endcapture %} 18 |
    19 | {{ code | markdownify }} 20 |
    -------------------------------------------------------------------------------- /_includes/snippets/oidc/user-info/request.md: -------------------------------------------------------------------------------- 1 | {% capture code %} 2 | ``` 3 | GET https://idp.int.identitysandbox.gov/api/openid_connect/userinfo 4 | Authorization: Bearer hhJES3wcgjI55jzjBvZpNQ 5 | ``` 6 | {% endcapture %} 7 |
    8 | {{ code | markdownify }} 9 |
    -------------------------------------------------------------------------------- /_includes/snippets/oidc/user-info/response.md: -------------------------------------------------------------------------------- 1 | {% capture code %} 2 | ```json 3 | { 4 | "address": { 5 | "formatted": "123 Main St Apt 123\nWashington, DC 20001", 6 | "street_address": "123 Main St Apt 123", 7 | "locality": "Washington", 8 | "region": "DC", 9 | "postal_code": "20001" 10 | }, 11 | "birthdate": "1970-01-01", 12 | "email": "test@example.com", 13 | "email_verified": true, 14 | "all_emails": ["test@example.com", "test2@example.com"], 15 | "locale": "en", 16 | "family_name": "Smith", 17 | "given_name": "John", 18 | "iss": "https://idp.int.identitysandbox.gov", 19 | "phone": "+18881112222", 20 | "phone_verified": true, 21 | "social_security_number": "111223333", 22 | "sub": "b2d2d115-1d7e-4579-b9d6-f8e84f4f56ca", 23 | "verified_at": 1577854800 24 | } 25 | ``` 26 | {% endcapture %} 27 |
    28 | {{ code | markdownify }} 29 |
    30 | -------------------------------------------------------------------------------- /_includes/snippets/saml/auth/request.md: -------------------------------------------------------------------------------- 1 | {% capture request %} 2 | ```bash 3 | https://idp.int.identitysandbox.gov/api/saml/auth{{ site.data.saml.year.current }}?SAMLRequest=${SAML_REQUEST} 4 | ``` 5 | {% endcapture %} 6 |
    7 | {{ request | markdownify }} 8 |
    9 | -------------------------------------------------------------------------------- /_includes/snippets/saml/auth/request_example.md: -------------------------------------------------------------------------------- 1 | {% capture example %} 2 | ```xml 3 | 10 | urn:gov:gsa:SAML:2.0.profiles:sp:sso:rails-int 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | Tkwp/uId8ZLwmvPaq2yuIj+h2kM8gjIQEQer7+kBrQM= 24 | 25 | 26 | n0PPcU29EfMzKq1O066+UzWwFs/K7IumAuXpve3fGmpHXEWAspMV4/Kkfc9gaRLq/eIMoh0yyv+n0U+7h2N/pYw26Y9LpLfVvK03HRDiGNKib36FeBQOINTWwvIcPZYqCL23IjfP4TO+RFt936f74HQSGZMa3a4ZQ4flY0BPV9BD/WrjBFRvY51V993JOS10S1mXPlZlX/UFCsa1mh9GQz15rZ1nL09iYiy5rNm0OMOcd2HphFYOyJrA7XloIgL7XjRMSKzTYvUTchDn26evRior1u22jBwFGEX26z+aSdc8GWhq1beK1NCDHLUX+TI2bc4U0ENSNRDFDghaH8F/Ig== 27 | 28 | 29 | MIIDejCCAmICCQDxlELhbJBQdzANBgkqhkiG9w0BAQUFADB/MRYwFAYDVQQDDA1TUCBSYWlscyBEZW1vMQwwCgYDVQQKDANHU0ExDDAKBgNVBAsMAzE4ZjETMBEGA1UEBwwKV2FzaGluZ3RvbjELMAkGA1UECAwCREMxCzAJBgNVBAYTAlVTMRowGAYJKoZIhvcNAQkBFgsxOGZAZ3NhLmdvdjAeFw0xNjA4MTgyMDIzMzNaFw0yNjA4MTYyMDIzMzNaMH8xFjAUBgNVBAMMDVNQIFJhaWxzIERlbW8xDDAKBgNVBAoMA0dTQTEMMAoGA1UECwwDMThmMRMwEQYDVQQHDApXYXNoaW5ndG9uMQswCQYDVQQIDAJEQzELMAkGA1UEBhMCVVMxGjAYBgkqhkiG9w0BCQEWCzE4ZkBnc2EuZ292MIIBIjANBgkqhk 30 | 31 | 32 | 33 | 35 | 36 | urn:acr.login.gov:auth-only 37 | http://idmanagement.gov/ns/requested_attributes?ReqAttr=email,phone,first_name,last_name,ssn 38 | 39 | 40 | ``` 41 | {% endcapture %} 42 |
    43 | {{ example | markdownify }} 44 |
    -------------------------------------------------------------------------------- /_includes/snippets/saml/auth/response.md: -------------------------------------------------------------------------------- 1 | {% capture response %} 2 | ```bash 3 | POST ${ASSERTION_CONSUMER_SERVICE_URL} 4 | SAMLResponse=${SAML_RESPONSE} 5 | ``` 6 | {% endcapture %} 7 |
    8 | {{ response | markdownify }} 9 |
    -------------------------------------------------------------------------------- /_includes/snippets/saml/auth/response_example.md: -------------------------------------------------------------------------------- 1 | {% capture example %} 2 | ```xml 3 | 10 | https://idp.int.identitysandbox.gov/api/saml 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | MIIDejCCAmICCQDxlELhbJBQdzANBgkqhkiG9w0BAQUFADB/MRYwFAYDVQQDDA1TUCBSYWlscyBEZW1vMQwwCgYDVQQKDANHU0ExDDAKBgNVBAsMAzE4ZjETMBEGA1UEBwwKV2FzaGluZ3RvbjELMAkGA1UECAwCREMxCzAJBgNVBAYTAlVTMRowGAYJKoZIhvcNAQkBFgsxOGZAZ3NhLmdvdjAeFw0xNjA4MTgyMDIzMzNaFw0yNjA4MTYyMDIzMzNaMH8xFjAUBgNVBAMMDVNQIFJhaWxzIERlbW8xDDAKBgNVBAoMA0dTQTEMMAoGA1UECwwDMThmMRMwEQYDVQQHDApXYXNoaW5ndG9uMQswCQYDVQQIDAJEQzELMAkGA1UEBhMCVVMxGjAYBgkqhkiG9w0BCQEWCzE4ZkBnc2EuZ292MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6gWv5EDu88CgWTgo+B8+Rp7ZSjNKKdud2I4U6Bfr0IMerdrh1LVwO6JOli/qRRDqECQz7Jm6m4XnVvf1bUiQd8cn/FheQfD2NuDNfrnAvyIRIHDgGHGSx3vjPZJVYi5BVmEOPFEKYEKHqS/UGnNjkS2XsoAkstRe6gioo4Hd2WLwjuCMqgNA3vgwyVxdgfI5vsrm6q43X15wb/wCP4r2rGKGSUIIshZPeUcPOzBMAmwVqREN4ux79Ee5K/87aXBVRF7Z2tFV1d5KEXO3dCw+T6cspj9MjfY2976cQfBXWnDKGdNWaLdwtFqvpgo9IXRxlAmUQtx8SC8z+zXaSSGB/wIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQCtc97SZLs5eBx7LrxdaeP5hq2etB7l6uM6+l/eSvXu8LlQfTUT7URxX4hXbKyORs1BLpnMYxofeyJlzb9K0koy1ZFhUtBufvU1R+ouMfZlV3QGOUMIUp00UNS39b74214jpuUYi7oEM0gHBN3BXxVyzUEAzt2HYHp2Im97ERSmTMkvSfiqilx/t03qIuZVxzu+jIU2BQUxS7s6XQ2DpDbvfggmnvToCmNA0VSg9rZkziOLSRHblcUpdMYH8+mzbTCfgg/Of0kTDVqXzgNa/iR0HUq18bDf3iFebS/sugwXN3vCxdCnad64q5tqF+VscZEtc7Okech2OuctnWy0nzFQ 24 | 25 | 26 | 27 | yaI+Z9oWcrP2WL02UdN7wdeoloWSBuz4nrFKh+vuyHitlk3A3/ATy4rtHerREue6uEYJ2sr7RoJbF/pqsr1j2ZWGJRL9FS++i0biE9iv3NwrW1MDvzGAaMiI9q+tmDqhorftiD+0byrtftZU2Emmwz34/bZJQKFszDeWlDrTVIXGDz+jF0Q+AvFxtaMrXXw6VmLlQlM/Hc9GiGCY+yalGmlteAJD+xk9aqUqfO9+qbwqufLQTpLyM8UdjHuwN9V4ZEo09er34SZD3ZhGq7IdWvROpcPeagU2+r6pivCmhY3x1t01uDtKe0jDt8LTGA1/P8atB3zQHkNnbGO1CiBKpg== 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | vy4Ohper0Oq24kU9GBTr0L8dHSBLkRpeu/iNr790cOQrAKphfPRCtLR7RHFI0mTCiko+Wy/oQqX4gu0LVtOOkcjJIicDyuWhIF6guUHvHz1PP4cv3pG++EhAJ73dbCPFSFkrDCzyMM5KZaY0xj6GpcYAVhOjez2ooOqwyTRYVpgozyuIreuooNFV8K++6GixLfBjw9T47eokKqLiROcRjEpV1dBoIkr34KtA7+TCrms1tLwAv4mdzCpUa7j 36 | 37 | 38 | 39 | 40 | ``` 41 | {% endcapture %} 42 |
    43 | {{ example | markdownify }} 44 |
    -------------------------------------------------------------------------------- /_includes/snippets/saml/logout/remote_logout.md: -------------------------------------------------------------------------------- 1 | {% capture remote_logout %} 2 | Login.gov also offers a remote / back channel logout endpoint if your application needs to log users out without redirecting them back to Login.gov. This is still **not** true Single Logout (SLO), it will only terminate a given user's session with Login.gov. You must still manage the session for your application separately. 3 | 4 | For remote logout, you must include a `SessionIndex` element in the SAML request that contains the user's Login.gov UUID. This will allow Login.gov to identify the user that needs to be logged out and terminate their session. 5 | 6 | To log a user out using a back channel request, send a **POST** request from your application to the remote logout URL with a `SAMLRequest` parameter: 7 | 8 | ```bash 9 | https://idp.int.identitysandbox.gov/api/saml/remotelogout{{ site.data.saml.year.current }}?SAMLRequest=${SAML_REQUEST} 10 | ``` 11 | 12 | The `SAMLRequest` parameter is a url-encoded, base64-encoded, deflate-compressed XML payload of a ``. 13 | 14 | All remote logout requests must be signed — we require RSA SHA-256 signatures embedded with logout requests. 15 | 16 | An example remote logout request payload, with indentation added for readability. 17 | 18 | ```xml 19 | 25 | urn:gov:gsa:SAML:2.0.profiles:sp:sso:rails-int 26 | e1e99d8e-c590-4e0d-9530-e4d9611a4509 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 3uM6/dwG6J2StsI9uFMlvpaLIHs2OqacTW9h7cGXOcE= 40 | 41 | 42 | zxIZQaHhakrKzV1vISwql0Ua8HKudlPDw3g7mcO18yFt6oDtCR55e7RlcuBOQYRYM5wesbxyAZcglJaxVVheViK9REg87OU1RqCJElyUcXXK6ERdgXpOp0YCb/VorWU4y9UNrloqFzgRIJxKtqVPqLlC6KSpqZqOiABhGluleUaIOuhW9INEwmQyWVobGp6+/ZOBY1m1DnMCaEmB46qW2YhYTCrBy6Uv3ZIs/sZZhlkyU98hndyVfJmzCRPzLmhHuxQunhqFLnbPoB3lCzOn2fV5oNYHOTmkDfb90HZoyd9gj5YOynmd6AQsUebx6utWTtyQ9sYojPixjehos8Yd5w== 43 | 44 | 45 | MIIDejCCAmICCQDxlELhbJBQdzANBgkqhkiG9w0BAQUFADB/MRYwFAYDVQQDDA1TUCBSYWlscyBEZW1vMQwwCgYDVQQKDANHU0ExDDAKBgNVBAsMAzE4ZjETMBEGA1UEBwwKV2FzaGluZ3RvbjELMAkGA1UECAwCREMxCzAJBgNVBAYTAlVTMRowGAYJKoZIhvcNAQkBFgsxOGZAZ3NhLmdvdjAeFw0xNjA4MTgyMDIzMzNaFw0yNjA4MTYyMDIzMzNaMH8xFjAUBgNVBAMMDVNQIFJhaWxzIERlbW8xDDAKBgNVBAoMA0dTQTEMMAoGA1UECwwDMThmMRMwEQYDVQQHDApXYXNoaW5ndG9uMQswCQYDVQQIDAJEQzELMAkGA1UEBhMCVVMxGjAYBgkqhkiG9w0BCQEWCzE4ZkBnc2EuZ292MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6gWv5EDu88CgWTgo+B8+Rp7ZSjNKKdud2I4U6Bfr0IMerdrh1LVwO6JOli/qRRDqECQz7Jm6m4XnVvf1bUiQd8cn/FheQfD2NuDNfrnAvyIRIHDgGHGSx3vjPZJVYi5BVmEOPFEKYEKHqS/UGnNjkS2XsoAkstRe6gioo4Hd2WLwjuCMqgNA3vgwyVxdgfI5vsrm6q43X15wb/wCP4r2rGKGSUIIshZPeUcPOzBMAmwVqREN4ux79Ee5K/87aXBVRF7Z2tFV1d5KEXO3dCw+T6cspj9MjfY2976cQfBXWnDKGdNWaLdwtFqvpgo9IXRxlAmUQtx8SC8z+zXaSSGB/wIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQCtc97SZLs5eBx7LrxdaeP5hq2etB7l6uM6+l/eSvXu8LlQfTUT7URxX4hXbKyORs1BLpnMYxofeyJlzb9K0koy1ZFhUtBufvU1R+ouMfZlV3QGOUMIUp00UNS39b74214jpuUYi7oEM0gHBN3BXxVyzUEAzt2HYHp2Im97ERSmTMkvSfiqilx/t03qIuZVxzu+jIU2BQUxS7s6XQ2DpDbvfggmnvToCmNA0VSg9rZkziOLSRHblcUpdMYH8+mzbTCfgg/Of0kTDVqXzgNa/iR0HUq18bDf3iFebS/sugwXN3vCxdCnad64q5tqF+VscZEtc7Okech2OuctnWy0nzFQ 46 | 47 | 48 | 49 | 4985175e-3ddb-489a-a92c-c981cd15e3ca 50 | 51 | ``` 52 | 53 | In response to a remote logout request Login.gov will render a [logout response](#logout-response). 54 | {% endcapture %} 55 |
    56 | {{ remote_logout | markdownify }} 57 |
    58 | -------------------------------------------------------------------------------- /_includes/snippets/saml/logout/request.md: -------------------------------------------------------------------------------- 1 | {% capture request %} 2 | ```bash 3 | https://idp.int.identitysandbox.gov/api/saml/logout{{ site.data.saml.year.current }}?SAMLRequest=${SAML_REQUEST} 4 | ``` 5 | {% endcapture %} 6 |
    7 | {{ request | markdownify }} 8 |
    9 | -------------------------------------------------------------------------------- /_includes/snippets/saml/logout/request_example.md: -------------------------------------------------------------------------------- 1 | {% capture example %} 2 | ```xml 3 | 9 | urn:gov:gsa:SAML:2.0.profiles:sp:sso:rails-int 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 3uM6/dwG6J2StsI9uFMlvpaLIHs2OqacTW9h7cGXOcE= 23 | 24 | 25 | zxIZQaHhakrKzV1vISwql0Ua8HKudlPDw3g7mcO18yFt6oDtCR55e7RlcuBOQYRYM5wesbxyAZcglJaxVVheViK9REg87OU1RqCJElyUcXXK6ERdgXpOp0YCb/VorWU4y9UNrloqFzgRIJxKtqVPqLlC6KSpqZqOiABhGluleUaIOuhW9INEwmQyWVobGp6+/ZOBY1m1DnMCaEmB46qW2YhYTCrBy6Uv3ZIs/sZZhlkyU98hndyVfJmzCRPzLmhHuxQunhqFLnbPoB3lCzOn2fV5oNYHOTmkDfb90HZoyd9gj5YOynmd6AQsUebx6utWTtyQ9sYojPixjehos8Yd5w== 26 | 27 | 28 | MIIDejCCAmICCQDxlELhbJBQdzANBgkqhkiG9w0BAQUFADB/MRYwFAYDVQQDDA1TUCBSYWlscyBEZW1vMQwwCgYDVQQKDANHU0ExDDAKBgNVBAsMAzE4ZjETMBEGA1UEBwwKV2FzaGluZ3RvbjELMAkGA1UECAwCREMxCzAJBgNVBAYTAlVTMRowGAYJKoZIhvcNAQkBFgsxOGZAZ3NhLmdvdjAeFw0xNjA4MTgyMDIzMzNaFw0yNjA4MTYyMDIzMzNaMH8xFjAUBgNVBAMMDVNQIFJhaWxzIERlbW8xDDAKBgNVBAoMA0dTQTEMMAoGA1UECwwDMThmMRMwEQYDVQQHDApXYXNoaW5ndG9uMQswCQYDVQQIDAJEQzELMAkGA1UEBhM 29 | 30 | 31 | 32 | 4985175e-3ddb-489a-a92c-c981cd15e3ca 33 | 34 | ``` 35 | {% endcapture %} 36 |
    37 | {{ example | markdownify }} 38 |
    -------------------------------------------------------------------------------- /_includes/snippets/saml/logout/response.md: -------------------------------------------------------------------------------- 1 | {% capture response %} 2 | ```bash 3 | POST ${ASSERTION_CONSUMER_SERVICE_LOGOUT_URL} 4 | SAMLResponse=${SAML_RESPONSE} 5 | ``` 6 | {% endcapture %} 7 |
    8 | {{ response | markdownify }} 9 |
    10 | -------------------------------------------------------------------------------- /_includes/snippets/saml/logout/response_example.md: -------------------------------------------------------------------------------- 1 | {% capture example %} 2 | ```xml 3 | 9 | https://idp.int.identitysandbox.gov/api/saml 10 | 11 | 12 | 13 | 14 | ``` 15 | {% endcapture %} 16 |
    17 | {{ example | markdownify }} 18 |
    -------------------------------------------------------------------------------- /_includes/support/oidc.html: -------------------------------------------------------------------------------- 1 |
    2 |

    OpenID Connect Errors

    3 |

    Authorization

    4 |
    5 | {% for error in site.data.errors.oidc.auth %} 6 | {% include accordion.html content=error.content accordion_id=error.accordion-id title=error.title id=error.id %} 7 | {% endfor %} 8 |
    9 |

    Logout

    10 |
    11 | {% for error in site.data.errors.oidc.logout %} 12 | {% include accordion.html content=error.content accordion_id=error.accordion-id title=error.title id=error.id %} 13 | {% endfor %} 14 |
    15 |

    Token

    16 |
    17 | {% for error in site.data.errors.oidc.token %} 18 | {% include accordion.html content=error.content accordion_id=error.accordion-id title=error.title id=error.id %} 19 | {% endfor %} 20 |
    21 |

    Userinfo endpoint

    22 |
    23 | {% for error in site.data.errors.oidc.userinfo %} 24 | {% include accordion.html content=error.content accordion_id=error.accordion-id title=error.title id=error.id %} 25 | {% endfor %} 26 |
    27 |
    28 | -------------------------------------------------------------------------------- /_includes/yaml: -------------------------------------------------------------------------------- 1 | ../assets/yaml -------------------------------------------------------------------------------- /_includes/yaml_download.md: -------------------------------------------------------------------------------- 1 | {% comment %} 2 | Include: 3 | - filename 4 | {% endcomment %} 5 | 6 | {% assign path = include.filename | prepend: 'yaml/' %} 7 | 8 | {%- capture data -%} 9 | {% include {{ path }} %} 10 | {%- endcapture %} 11 | 12 | ```yaml 13 | {{ data }} 14 | ``` 15 | 16 | 17 | Download .yml 18 | 19 | -------------------------------------------------------------------------------- /_layouts/base.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {% include osc_analytics.html %} 6 | {% include dap.html %} 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | {% capture title -%} 15 | {% if page.title %}{{ page.title }} | {{ site.title }}{% else %}{{ site.title }}{% endif -%} 16 | {% endcapture -%} 17 | 18 | {{ title }} 19 | 20 | 21 | {% if page.lead -%} 22 | 23 | 24 | {% endif -%} 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | Skip to main content 35 | 36 |
    37 |
    38 |
    39 |
    40 |
    41 | U.S. flag 42 |
    43 |
    44 |

    An official website of the United States government

    45 | 46 |
    47 | 51 |
    52 |
    53 |
    54 |
    55 |
    56 |
    57 | Dot gov 61 |
    62 |

    63 | Official websites use .gov 64 |
    65 | A .gov website belongs to an official government organization in the United States. 66 |

    67 |
    68 |
    69 |
    70 | Https 74 |
    75 |

    76 | Secure .gov websites use HTTPS 77 |
    78 | A lock ( 79 | Https 83 | ) or https:// means you've safely connected to the .gov website. Share sensitive information only on official, secure websites. 84 |

    85 |
    86 |
    87 |
    88 |
    89 |
    90 |
    91 |
    92 | 93 |
    94 | 148 | 149 | {{ content }} 150 | 151 | {% include footer.html %} 152 | 153 | 154 | 155 | 156 | 157 | 165 | 166 | 167 | 168 | 169 | -------------------------------------------------------------------------------- /_layouts/documentation.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: base 3 | --- 4 | 5 |
    6 |
    7 | {% if page.sidenav %} 8 |
    9 |
    10 | 22 |
    23 | 24 |
    25 | 26 | {% if site.temporary_alert %} 27 | {% include alert.html content=site.temporary_alert %} 28 | {% endif %} 29 | 30 | {% if page.lead == null %} 31 |

    {{ page.title }}

    32 | {% endif %} 33 | 34 | 35 | {{ content }} 36 | 37 | Edit this page 38 |
    39 | 40 | Return to top 41 |
    42 | {% else %} 43 |
    44 | 45 | {% if site.temporary_alert %} 46 | {% include alert.html content=site.temporary_alert %} 47 | {% endif %} 48 | 49 |

    {{ page.title }}

    50 | 51 | {% if page.lead %} 52 |
    {{ page.lead | markdownify }}
    53 | {% endif %} 54 | 55 | 56 | 57 | {{ content }} 58 | 59 | 60 |
    61 | {% endif %} 62 |
    63 |
    64 | -------------------------------------------------------------------------------- /_layouts/home.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: base 3 | --- 4 | 5 |
    6 | {{ content }} 7 |
    8 | -------------------------------------------------------------------------------- /_layouts/not_found.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {% include osc_analytics.html %} 6 | {% include dap.html %} 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | {% capture title -%} 15 | {% if page.title %}{{ page.title }} | {{ site.title }}{% else %}{{ site.title }}{% endif -%} 16 | {% endcapture -%} 17 | 18 | {{ title }} 19 | 20 | 21 | {% if page.lead -%} 22 | 23 | 24 | {% endif -%} 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | {{ content }} 35 | 36 | 37 | -------------------------------------------------------------------------------- /_pages/404.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: not_found 3 | title: This page is no longer available. 4 | permalink: /404.html 5 | sitemap: false 6 | --- 7 | 8 |
    9 |
    10 |
    11 |
    12 |
    13 | Login.gov logo 14 |
    15 |
    16 |
    17 |

    18 | The page you are looking for may have moved or is no longer available. 19 |

    20 |

    21 | Please check the URL. 22 |

    23 |

    24 | Here are some links that might be helpful: 25 |

    26 |
    27 | 31 |
    32 |
    33 |
    34 | -------------------------------------------------------------------------------- /_pages/attributes.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: User attributes 3 | lead: > 4 | Login.gov user accounts are either identity proofed or self-asserted. 5 | --- 6 | 7 | Here are the possible attributes that can be requested at a given IAL. This table contains the available user attributes, the IAL they are associated with, and how they can be accessed in OpenID Connect (OIDC) and SAML. 8 | 9 | It is important to expect any number of characters in the `(string)` datatype unless directly followed by a number such as `(string36)`. Strings are encrypted and stored in a text datatype with a maximum length of 65,535 bytes. 10 | 11 | 12 | {% capture checkmark %} 13 |
    14 | 15 | 16 | 17 |
    18 | {% endcapture %} 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 33 | 36 | 39 | 42 | 45 | 46 | 47 | 50 | 53 | 56 | 61 | 64 | 65 | 66 | 69 | 72 | 75 | 78 | 81 | 82 | 83 | 86 | 89 | 92 | 95 | 98 | 99 | 100 | 103 | 106 | 109 | 114 | 119 | 120 | 121 | 124 | 127 | 130 | 135 | 140 | 141 | 142 | 145 | 146 | 149 | 154 | 157 | 158 | 159 | 162 | 163 | 166 | 171 | 174 | 175 | 176 | 179 | 180 | 183 | 194 | 201 | 202 | 203 | 206 | 207 | 210 | 215 | 218 | 219 | 220 | 223 | 224 | 227 | 232 | 235 | 236 | 237 | 241 | 242 | 245 | 250 | 253 | 254 | 255 | 259 | 262 | 265 | 272 | 275 | 276 | 277 | 280 | 283 | 286 | 293 | 296 | 297 | 298 | 301 | 304 | 307 | 312 | 315 | 316 | 317 | 320 | 323 | 326 | 331 | 334 | 335 | 336 | 339 | 342 | 345 | 350 | 353 | 354 | 355 |
    AttributeAuth OnlyID ProofedOpenID ConnectSAML
    31 | **UUID**
    The user's [universally unique identifier](https://en.wikipedia.org/wiki/Universally_unique_identifier). 32 |
    34 | {{ checkmark }} 35 | 37 | {{ checkmark }} 38 | 40 | `sub` (string36) 41 | 43 | `uuid` (string36) 44 |
    48 | **Email**
    The user's email address. 49 |
    51 | {{ checkmark }} 52 | 54 | {{ checkmark }} 55 | 57 | `email` (string) 58 | 59 | Requires the `email` scope. 60 | 62 | `email` (string) 63 |
    67 | **All emails**
    All of the email addresses on the user's account. 68 |
    70 | {{ checkmark }} 71 | 73 | {{ checkmark }} 74 | 76 | `all_emails` (array of strings) 77 | 79 | `all_emails` (array of strings) 80 |
    84 | **Locale**
    The user's language preference. 85 |
    87 | {{ checkmark }} 88 | 90 | {{ checkmark }} 91 | 93 | `locale` (string, ISO 639-1 language code) 94 | 96 | `locale` (string, ISO 639-1 language code) 97 |
    101 | **IAL**
    Identity Assurance Level [NIST 800-63-3](https://pages.nist.gov/800-63-3/). 102 |
    104 | {{ checkmark }} 105 | 107 | {{ checkmark }} 108 | 110 | `ial` (url, urn) 111 | 112 | See [OpenID Connect IAL values](/oidc/authorization/#service_level) 113 | 115 | `ial` (url, urn) 116 | 117 | See [SAML IAL values](/saml/authentication/#service_level) 118 |
    122 | **AAL**
    Authenticator Assurance Level [NIST 800-63-3](https://pages.nist.gov/800-63-3/). 123 |
    125 | {{ checkmark }} 126 | 128 | {{ checkmark }} 129 | 131 | `aal` (url, urn) 132 | 133 | See [OpenID Connect AAL values](/oidc/authorization/#aal_values) 134 | 136 | `aal` (url, urn) 137 | 138 | See [SAML AAL values](/saml/authentication/#aal_values) 139 |
    143 | **First name**
    The user's first (given) name. 144 |
    147 | {{ checkmark }} 148 | 150 | `given_name` (string) 151 | 152 | Requires `profile` or `profile:name` scopes. 153 | 155 | `first_name` (string) 156 |
    160 | **Last name**
    The user's last (family) name. 161 |
    164 | {{ checkmark }} 165 | 167 | `family_name` (string) 168 | 169 | Requires `profile` or `profile:name` scopes. 170 | 172 | `last_name` (string) 173 |
    177 | **Address**
    The user's address, including street, city, state, and zip code. 178 |
    181 | {{ checkmark }} 182 | 184 | `address` (object) 185 | 186 | The [address claim](https://openid.net/specs/openid-connect-core-1_0.html#AddressClaim), containing:
    187 | `street_address` (string)
    188 | `locality` (city, string)
    189 | `region` (state, string)
    190 | `postal_code` (zip code, string5) 191 |

    192 | Requires the `address` scope. 193 |
    195 | `address1` (string)
    196 | `address2` (string)
    197 | `city` (string)
    198 | `state` (string)
    199 | `zipcode` (string5) 200 |
    204 | **Phone***
    The user's phone number formatted as [E.164](https://en.wikipedia.org/wiki/E.164), for example: `+18881112222`. 205 |
    208 | {{ checkmark }} 209 | 211 | `phone` (string, null) 212 | 213 | Requires the `phone` scope. 214 | 216 | `phone` (string, null) 217 |
    221 | **Date of birth**
    Formatted as [ISO 8601:2004](https://en.wikipedia.org/wiki/ISO_8601), for example: `YYYY-MM-DD`. 222 |
    225 | {{ checkmark }} 226 | 228 | `birthdate` (string10) 229 | 230 | Requires `profile` or `profile:birthdate` scopes. 231 | 233 | `dob` (string10) 234 |
    238 | **Social security number**
    239 | Example:
    `111-11-1111` 240 |
    243 | {{ checkmark }} 244 | 246 | `social_security_number` (string11) 247 | 248 | Requires the `social_security_number` scope. 249 | 251 | `ssn` (string11) 252 |
    256 | **Verification timestamp***
    257 | When the user's identity was last verified (or empty if it has never been verified). 258 |
    260 | {{ checkmark }} 261 | 263 | {{ checkmark }} 264 | 266 | `verified_at` (number, null) 267 | 268 | Seconds since the Unix Epoc 269 | 270 | Requires the `profile:verified_at` scope. 271 | 273 | `verified_at` (string, ISO8601 format) 274 |
    278 | **x509**
    279 |
    281 | {{ checkmark }} 282 | 284 | {{ checkmark }} 285 | 287 | `x509_issuer` (string) 288 | `x509_presented` (string) 289 | `x509_subject` (string) 290 | 291 | Requires the `x509` scope. 292 | 294 | n/a 295 |
    299 | **x509 Issuer**
    300 |
    302 | {{ checkmark }} 303 | 305 | {{ checkmark }} 306 | 308 | `x509_issuer` (string) 309 | 310 | Requires the `x509:issuer` or `x509` scope. 311 | 313 | `x509_issuer` (string) 314 |
    318 | **x509 Subject**
    319 |
    321 | {{ checkmark }} 322 | 324 | {{ checkmark }} 325 | 327 | `x509_subject` (string) 328 | 329 | Requires the `x509:subject` or `x509` scope. 330 | 332 | `x509_subject` (string) 333 |
    337 | **x509 Presented**
    338 |
    340 | {{ checkmark }} 341 | 343 | {{ checkmark }} 344 | 346 | `x509_presented` (boolean) 347 | 348 | Requires the `x509:presented` or `x509` scope. 349 | 351 | `x509_presented` (string) 352 |
    356 | * Please note that only `phone` and `verified_at` idV user attributes may be returned as null. 357 | 358 | [checkmark]: {{ site.baseurl }}/assets/img/check.svg 359 | -------------------------------------------------------------------------------- /_pages/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Welcome to the Login.gov developer guide 3 | lead: > 4 | This developer guide contains everything you’ll need to integrate and deploy your application with Login.gov. 5 | permalink: / 6 | layout: home 7 | --- 8 | 9 |
    10 |
    11 | {% if site.temporary_alert %} 12 |
    13 | {% include alert.html content=site.temporary_alert %} 14 |
    15 | {% endif %} 16 |

    How to integrate with Login.gov

    17 |
      18 |
    1. 19 |

      20 | Your integration with Login.gov starts in the portal where you can register your app. 21 |

      22 |
    2. 23 |
    3. 24 |

      25 | Determine your application needs, like the level of proofing and user attributes that will be requested. 26 |

      27 |
    4. 28 |
    5. 29 |

      30 | Select between Open ID Connect (OIDC) or SAML implementation protocols. 31 |

      32 |
    6. 33 |
    7. 34 |

      35 | Configure your app in the portal and start testing! We have implementation guides and example apps to get you up and running quickly. 36 |

      37 |
    8. 38 |
    9. 39 |

      40 | When you are ready to go live our team will help you promote the application to production. We will check against our production checklist to ensure your application is ready for production from an administrative and technical standpoint. 41 |

      42 |
    10. 43 |
    44 |
    45 |
    46 |

    Integration support for developers

    47 |

    48 | If you are with a government agency partner, check our [FAQ]({{ site.baseurl}}/support/#frequently-asked-questions) page for answers to the most common questions. If you need further technical assistance with an integration, you can [contact Partner Support]({{ site.baseurl}}/support/#contacting-partner-support). 49 |

    50 |

    51 | For help signing in or verifying your identity with Login.gov, please visit the Login.gov Help Center or contact us. 52 |

    53 |
    54 |
    55 |
    56 | -------------------------------------------------------------------------------- /_pages/oidc/certificates.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: OpenID Connect 3 | lead: > 4 | [OpenID Connect](https://openid.net){:class="usa-link--external"} (OIDC) is a simple identity layer built on top of the OAuth 2.0 protocol. Login.gov supports [version 1.0](https://openid.net/specs/openid-connect-core-1_0.html){:class="usa-link--external"} of the specification and conforms to the [iGov Profile](https://openid.net/wg/igov){:class="usa-link--external"}. 5 | sidenav: 6 | - text: Getting started 7 | href: "oidc/getting-started/" 8 | - text: Authorization 9 | href: "oidc/authorization/" 10 | - text: Token 11 | href: "oidc/token/" 12 | - text: User info 13 | href: "oidc/user-info/" 14 | - text: Certificates 15 | href: "oidc/certificates/" 16 | - text: Logout 17 | href: "oidc/logout/" 18 | 19 | --- 20 | 21 | {% capture content %} 22 | ## Certificates 23 | 24 | Login.gov's public key, used to verify signed JWTs (such as the `id_token`), is available in [JWK](https://tools.ietf.org/html/rfc7517){:class="usa-link--external"} format at the `/api/openid_connect/certs` endpoint. 25 | 26 | This public key is rotated periodically (on at least an annual basis). It is important to assume the `/api/openid_connect/certs` endpoint could contain multiple JWKs when rotating application signing keys. Be sure to use the JWK endpoint dynamically through [auto-discovery](/oidc/getting-started/#auto-discovery) rather than hardcoding the public key. This ensures that your application will not require manual intervention when the Login.gov public key is rotated. 27 | {% endcapture %} 28 | 29 |
    30 |
    31 | {{ content | markdownify }} 32 | Next step: Logout 33 |
    34 |
    35 |
    36 | OpenSSL Command 37 | {% include snippets/oidc/certificates.md %} 38 |
    39 |
    40 | Next step: Logout 41 |
    42 | -------------------------------------------------------------------------------- /_pages/oidc/getting-started.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: OpenID Connect 3 | lead: > 4 | [OpenID Connect](https://openid.net){:class="usa-link--external"} (OIDC) is a simple identity layer built on top of the OAuth 2.0 protocol. Login.gov supports [version 1.0](https://openid.net/specs/openid-connect-core-1_0.html){:class="usa-link--external"} of the specification and conforms to the [iGov Profile](https://openid.net/wg/igov){:class="usa-link--external"}. 5 | redirect_from: 6 | - /openid-connect/ 7 | - /oidc/ 8 | sidenav: 9 | - text: Getting started 10 | href: "oidc/getting-started/" 11 | links: 12 | - text: Choosing an authentication method 13 | href: "#choosing-an-authentication-method" 14 | - text: Set up a Sandbox account 15 | href: "#set-up-a-sandbox-account" 16 | - text: Auto-discovery 17 | href: "#auto-discovery" 18 | - text: Example application 19 | href: "#example-application" 20 | - text: Authorization 21 | href: "oidc/authorization/" 22 | - text: Token 23 | href: "oidc/token/" 24 | - text: User info 25 | href: "oidc/user-info/" 26 | - text: Certificates 27 | href: "oidc/certificates/" 28 | - text: Logout 29 | href: "oidc/logout/" 30 | 31 | --- 32 | {% capture implicit_flow_warning %} 33 | We do not support the OpenID Connect (OIDC) “implicit flow” with client_secret because it is not recommended by the OAuth group for security reasons 34 | {% endcapture %} 35 | {% include alert.html content=implicit_flow_warning alert_class="usa-alert--warning" %} 36 | 37 | 38 | ## Getting started 39 | 40 | ### Choosing an authentication method 41 | 42 | Login.gov supports two ways of authenticating clients: **private_key_jwt** and **PKCE**. 43 | 44 | - **private_key_jwt** (preferred for web apps) 45 | The client sends a [JSON Web Token](https://jwt.io/){:class="usa-link--external"}, or JWT, signed with a private key (minimum length of 2048 bits) when requesting access tokens. The corresponding public key is registered with the IdP ahead of time, similar to SAML. 46 | 47 | - **PKCE** (preferred for native mobile apps) 48 | Short for [Proof Key for Code Exchange by OAuth Public Clients](https://tools.ietf.org/html/rfc7636){:class="usa-link--external"} and pronounced "pixy." In this method, the client sends a public identifier as well as a hashed random value generated by the client. 49 | 50 | ### Unsupported methods 51 | 52 | The following implementation methods of OIDC are not supported by Login.gov for security reasons. 53 | 54 | - **Implicit flow** is [not recommended by the OAuth group](https://oauth.net/2/grant-types/implicit/){:class="usa-link--external"}. 55 | - **client_secret_param** is not supported because it requires managing a shared secret in two places, both the client and the server. Private_key_jwt flow involves sharing public keys with the server and PKCE has a one-time secret. 56 | 57 | ### Set up a Sandbox account 58 | 59 | You are able to test authentication methods in real time with a testing account in our sandbox environment. To start, navigate to the [Login Partner Portal Sandbox](https://dashboard.int.identitysandbox.gov) and follow the steps below: 60 | 61 | - Select the “Sign-in” button to create a new account. Anyone with a .gov or .mil email address may request an account. 62 | - Create a new team - see [Testing](/testing/) page for instructions. 63 | - Create a certificate - before creating your application you'll need to create a certificate that will be used to sign your requests. You can create a certificate using openssl. The example command to create the certificate from your terminal is: 64 | - `openssl req -nodes -x509 -days 365 -newkey rsa:2048 -keyout private.pem -out public.crt` 65 | - Create an application, at which point you will need to decide between private_key_jwt or PKCE. 66 | 67 | It is important to note that your Login.gov production account and your Login.gov sandbox account are two separate accounts. 68 | 69 | ### Auto-discovery 70 | 71 | Consistent with the specification, Login.gov provides a JSON endpoint for OIDC auto-discovery at 72 | `/.well-known/openid-configuration`. 73 | 74 | Integration URI: 75 | - [https://idp.int.identitysandbox.gov/.well-known/openid-configuration](https://idp.int.identitysandbox.gov/.well-known/openid-configuration) 76 | 77 | Production URI: 78 | - [https://secure.login.gov/.well-known/openid-configuration](https://secure.login.gov/.well-known/openid-configuration) 79 | 80 | ### Example Application 81 | 82 | The Login.gov team has created an example client to speed up your development, all open source in the public domain: [identity-oidc-sinatra](https://github.com/18F/identity-oidc-sinatra){:class="usa-link--external"}. 83 | 84 | [Next step: Authorization]({{ site.baseurl }}/oidc/authorization/){:class="margin-top-4"} 85 | -------------------------------------------------------------------------------- /_pages/oidc/logout.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: OpenID Connect 3 | lead: > 4 | [OpenID Connect](https://openid.net){:class="usa-link--external"} (OIDC) is a simple identity layer built on top of the OAuth 2.0 protocol. Login.gov supports [version 1.0](https://openid.net/specs/openid-connect-core-1_0.html){:class="usa-link--external"} of the specification and conforms to the [iGov Profile](https://openid.net/wg/igov){:class="usa-link--external"}. 5 | sidenav: 6 | - text: Getting started 7 | href: "oidc/getting-started/" 8 | - text: Authorization 9 | href: "oidc/authorization/" 10 | - text: Token 11 | href: "oidc/token/" 12 | - text: User info 13 | href: "oidc/user-info/" 14 | - text: Certificates 15 | href: "oidc/certificates/" 16 | - text: Logout 17 | href: "oidc/logout/" 18 | links: 19 | - text: Logout request 20 | href: "#logout-request" 21 | - text: Logout response 22 | href: "#logout-response" 23 | 24 | --- 25 | 26 |
    27 |
    28 | 29 | ## Logout 30 | 31 | Login.gov supports [RP-Initiated Logout](https://openid.net/specs/openid-connect-rpinitiated-1_0.html){:class="usa-link--external"}, allowing clients to log users out of their current Login.gov session and redirect them back to the Relying Party. 32 | 33 | Login.gov does not support Single Logout (SLO). The logout action will terminate the user’s session at Login.gov but will not end any other potentially active sessions within service provider applications. For example, if a user signs in to applications A and B through Login.gov, a logout request from A will end their Login.gov session, but will not affect the session in application B. 34 | 35 | **User experience impact:** 36 | 37 | As per the OIDC spec, Login.gov will display a Logout confirmation screen to users on logout. Users will need to click a button to complete the logout process. This protects against forged logout request attacks. 38 | 39 | If the user does not click the button, they will **not** be redirected back to your application. 40 | 41 | ### Logout request 42 | 43 | To log out a user, send them to the `/openid_connect/logout` endpoint with the following parameters: 44 | 45 |
    46 |
    47 |
    48 |

    client_id

    49 |
    50 |
    51 |

    52 | The unique identifier for the client. This will be registered with the Login.gov IdP in advance. 53 |

    54 |
    55 |
    56 |
    57 |
    58 |
    59 |
    60 |

    post_logout_redirect_uri

    61 |
    62 |
    63 |

    64 | The URI Login.gov will redirect to after logout. This must also be registered with the Login.gov IdP in advance. 65 |

    66 |
    67 |
    68 |
    69 |
    70 |
    71 |
    72 |

    state (optional)

    73 |
    74 |
    75 |

    76 | A unique value at least 22 characters in length used for maintaining state between the request and the callback. This value will be returned to the client on a successful logout as a parameter of state added to the redirect back to the post_logout_redirect_uri. 77 |

    78 |
    79 |
    80 |
    81 | 82 | ### Logout response 83 | 84 | In a **successful logout**, i.e. the request is valid and the user confirms that they want to log out, Login.gov will redirect the user to the provided `post_logout_redirect_uri` with the `state` parameter added to the URL. If the request is invalid, the user will be shown an error page. 85 | 86 | If the user declines to click the button on the confirmation page, they will not be redirected to the `post_logout_redirect_uri` and there will be no response to your application. 87 | 88 | 89 |
    90 | 91 |
    92 |
    93 | 94 | 95 |
    96 | {% include snippets/oidc/logout/request.md %} 97 |
    98 | 101 |
    102 |
    103 |
    104 | -------------------------------------------------------------------------------- /_pages/oidc/user-info.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: OpenID Connect 3 | lead: > 4 | [OpenID Connect](https://openid.net){:class="usa-link--external"} (OIDC) is a simple identity layer built on top of the OAuth 2.0 protocol. Login.gov supports [version 1.0](https://openid.net/specs/openid-connect-core-1_0.html){:class="usa-link--external"} of the specification and conforms to the [iGov Profile](https://openid.net/wg/igov){:class="usa-link--external"}. 5 | sidenav: 6 | - text: Getting started 7 | href: "oidc/getting-started/" 8 | - text: Authorization 9 | href: "oidc/authorization/" 10 | - text: Token 11 | href: "oidc/token/" 12 | - text: User info 13 | href: "oidc/user-info/" 14 | links: 15 | - text: User info response 16 | href: "#user-info-response" 17 | - text: Certificates 18 | href: "oidc/certificates/" 19 | - text: Logout 20 | href: "oidc/logout/" 21 | 22 | --- 23 | {% capture front_matter %} 24 | ## User info 25 | 26 | The user info endpoint is used to retrieve [user attributes]({{ site.baseurl }}/attributes/). Clients use the `access_token` from the [token response]({{ site.baseurl }}/oidc/token/#token-response) as a bearer token in the [HTTP Authorization header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Authorization){:class="usa-link--external"}. To request attributes, send an HTTP GET request to the `/api/openid_connect/userinfo` endpoint. View an example request and response in the side panel. 27 | 28 | ### User info response 29 | 30 | The user info response will be a JSON object containing [user attributes]({{ site.baseurl }}/attributes/). Login.gov supports some of the [standard claims](https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims){:class="usa-link--external"} from OIDC 1.0. In addition to the user attributes, the following information will also be present: 31 | {% endcapture %} 32 | 33 |
    34 |
    35 | {{ front_matter | markdownify }} 36 |
    37 |
    38 |

    iss (string)

    39 |
    40 |
    41 |

    42 | The issuer of the response, which will be the URL of the Login.gov IdP, for example: https://idp.int.identitysandbox.gov 43 |

    44 |
    45 |
    46 |
    47 |
    48 |

    email_verified (boolean)

    49 |
    50 |
    51 |

    52 | Whether the email has been verified. Currently, Login.gov only supports verified emails. 53 |

    54 |
      55 |
    • Requires email scope
    • 56 |
    57 |
    58 |
    59 |
    60 |
    61 |

    phone_verified (boolean)

    62 |
    63 |
    64 |

    65 | Whether the phone number has been verified. Currently, Login.gov only supports verified phones. 66 |

    67 |
      68 |
    • Requires the phone scope and an identity verified account
    • 69 |
    70 |
    71 |
    72 |
    73 |
    74 |

    verified_at (number, null)

    75 |
    76 |
    77 |

    78 | When the user's identity was last verified, as an integer timestamp representing the number of seconds since the Unix Epoch, or null if the account has never been verified. 79 |

    80 |
      81 |
    • Requires the profile:verified_at scope
    • 82 |
    83 |
    84 |
    85 | Next step: Certificates 86 |
    87 |
    88 |
    89 | 90 | 91 |
    92 | {% include snippets/oidc/user-info/request.md %} 93 |
    94 | 97 |
    98 |
    99 | Next step: Certificates 100 |
    101 | 102 | -------------------------------------------------------------------------------- /_pages/overview.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Integration overview and user flow 3 | sidenav: 4 | - text: User flow 5 | href: "#user-flow" 6 | - text: Service provider configuration 7 | href: "#service-provider-configuration" 8 | --- 9 | 10 | Login.gov is a FedRAMP moderate approved multifactor authentication and identity proofing platform that makes online interactions with the U.S. government simple, efficient and intuitive. 11 | 12 | ## User flow 13 | 14 |
    15 | A diagram flow of IAL1 walkthrough experience 18 |
    Fig. 1: Authentication flow
    19 |
    20 | 21 | * Once you have successfully integrated your application with the Login.gov environment, users start at your application and are redirected back to Login.gov via [OpenID Connect (OIDC)]({{ site.baseurl }}/oidc/) or [SAML]({{ site.baseurl }}/saml/) protocols. 22 | * The service level you specify via the authentication request sent by your application will determine the type of verification required for the user’s account. Identity proofed accounts require the user to complete additional steps to verify their identity in addition to the Multifactor Authentication (MFA). 23 | * New users will create an account corresponding to the identity assurance level requested. Returning users will present their existing Login.gov credentials to authenticate with Login.gov. A new user to your application will consent to their information being shared with your application upon creating an account. 24 | * Upon successful completion of the account creation and authentication, users will be redirected back to your application with the [user attributes]({{ '/attributes/' | prepend: site.baseurl }}) that correspond to their user level. 25 | * With the attributes provided by Login.gov, your application will handle authorization of the user and assign roles and permissions. 26 | 27 | ## Service provider configuration 28 | 29 | This is the configuration for your application within Login.gov’s identity provider. In the sandbox environment, you will be able to determine the configuration yourself and decide what is the best fit for your needs. In the Login.gov production environment, we will manage the final configuration. 30 | To configure a test application in the sandbox environment: 31 | * Create an account in the [Login.gov Portal](https://portal.int.identitysandbox.gov). From here you will be able to test various configurations and determine what is right for your agency. 32 | * Select between [OIDC]({{ site.baseurl }}/oidc/) or [SAML]({{ site.baseurl }}/saml/) protocol implementation protocols and understand which user attributes are required. 33 | * If you have questions when testing your app, read through our [FAQs]({{ site.baseurl }}/support/) or submit a ticket to our [technical support help desk]({{ site.baseurl}}/support/#contacting-partner-support). 34 | * Before submitting a request to move your app to production, review the [User experience]({{ site.baseurl }}/design-guidelines/) page and the [Production]({{ site.baseurl }}/production/) page. Additional requirements, like a [signed Interagency agreement]({{ site.baseurl }}/production/#confirm-interagency-agreement-iaa) (IAA) and [agency logo]({{ site.baseurl }}/user-experience/agency-logo/), are described in these pages. 35 | -------------------------------------------------------------------------------- /_pages/push-notifications.md: -------------------------------------------------------------------------------- 1 | --- 2 | redirect_to: /security-events/ 3 | --- -------------------------------------------------------------------------------- /_pages/risc.json: -------------------------------------------------------------------------------- 1 | --- 2 | permalink: /data/risc.json 3 | layout: none 4 | --- 5 | {%- capture json -%} 6 | { 7 | "supported_events": [ 8 | {% for event in site.data.risc_incoming %} 9 | {% include risc_event.json event=event direction="incoming" %} 10 | , 11 | {% endfor %} 12 | {% for event in site.data.risc_outgoing %} 13 | {% include risc_event.json event=event direction="outgoing" %} 14 | {% unless forloop.last %},{% endunless %} 15 | {% endfor %} 16 | ] 17 | } 18 | {%- endcapture -%} 19 | {{ json | pretty_jsonify }} -------------------------------------------------------------------------------- /_pages/saml/authentication.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: SAML developer guide 3 | lead: > 4 | Login.gov is a standard SAML identity provider, adhering to the [Web Browser SSO Profile](https://en.wikipedia.org/wiki/SAML_2.0#Web_browser_SSO_profile){:class="usa-link--external"} with enhancements for [NIST 800-63-3](https://pages.nist.gov/800-63-3/){:class="usa-link--external"}. 5 | redirect_from: 6 | - /configuring-your-sp/ 7 | - /saml/ 8 | sidenav: 9 | - text: Getting started 10 | href: "/saml/getting-started/" 11 | - text: Authentication 12 | href: "/saml/authentication/" 13 | links: 14 | - text: Authentication request 15 | href: "/saml/authentication/#authentication-request" 16 | - text: Authentication response 17 | href: "/saml/authentication/#authentication-response" 18 | - text: Logout 19 | href: "/saml/logout/" 20 | --- 21 | {% capture aal_values %} 22 | {% include snippets/auth_content/aal_values.md %} 23 | {% endcapture %} 24 | {% capture service_levels %} 25 | {% include snippets/auth_content/service_levels.md %} 26 | {% endcapture %} 27 | {% capture deprecated_values %} 28 | {% include snippets/auth_content/deprecated_values.md %} 29 | {% endcapture %} 30 | {% capture saml_request_intro %} 31 | `SAML_REQUEST = urlEncode(base64(deflate(payload)))` 32 | {% endcapture %} 33 | {% capture saml_tag %} 34 | The `` tags (nested under `//samlp:AuthnRequest/samlp:RequestedAuthnContext/`) specify the type of identity verification, AAL (Authentication Assurance Level) and attributes requested. 35 | {% endcapture %} 36 | {% capture attributes %} 37 | To request specific attributes, list them (comma-separated) as the query parameter for `http://idmanagement.gov/ns/requested_attributes?ReqAttr=`. See the [user attributes]({{ '/attributes/' | prepend: site.baseurl }}) for the list of attributes that can be requested. 38 | 39 | #### Example specifying IAL, AAL, and attributes 40 | 41 | A proofed identity request at AAL2, with phishing resistent MFA, for email, phone, first name, last name, and SSN might look like: 42 | 43 | ```xml 44 | 45 | 46 | 47 | urn:acr.login.gov:verified 48 | http://idmanagement.gov/ns/assurance/aal/2?phishing_resistant=true 49 | http://idmanagement.gov/ns/requested_attributes?ReqAttr=email,phone,first_name,last_name,ssn 50 | 51 | 52 | ``` 53 | {% endcapture %} 54 | 55 |
    56 |
    57 |

    Authentication

    58 |

    Authentication request

    59 |

    To authenticate a user with Login.gov, direct them to our authentication URL with a SAML authentication request as a GET param.

    60 |

    The SAMLRequest parameter is a url-encoded, base64-encoded, deflate-compressed XML payload. IE: {{ saml_request_intro | markdownify }}

    61 |

    Note: We strongly encourage you to cryptographically sign authentication requests. In addition to providing increased security, this allows for seamless rotation of your application’s public certificate in the future. All signatures must use RSA SHA-256.

    62 |
    63 |
    64 |
    65 |

    Specifying attributes and assurance levels

    66 |
    67 |
    68 | {{ saml_tag | markdownify }} 69 |
    70 |
    71 |
    72 | {% include accordion.html content=service_levels accordion_id="service_level_accordion" title="Type of Service Level" id="service_level" %} 73 | {% include accordion.html content=aal_values accordion_id="aal_accordion" title="Authentication Assurance (AAL) Values" id="aal_values" %} 74 | {% include accordion.html content=attributes accordion_id="attributes_accordion" title="Attributes" id="attributes" %} 75 | {% include accordion.html content=deprecated_values accordion_id="deprecated_accordion" title="Deprecated Service Values" id="deprecated_values" %} 76 |
    77 |
    78 |
    79 |
    80 |
    81 |

    RelayState

    82 |
    83 |
    84 |

    If you need to pass any information about the request back to your application after the authentication process is complete (e.g. the path to direct the user to), you can include a RelayState query parameter with up to 80 bytes of information. This will be included in the response back to your application as per section 3.4.3 of the SAML 2.0 bindings spec.

    85 |

    https://idp.int.identitysandbox.gov/api/saml/auth2023?SAMLRequest=${SAML_REQUEST}&RelayState=${RELAY_STATE}

    86 |
    87 |
    88 |
    89 |
    90 |
    91 |
    92 |

    Language Selection

    93 |
    94 |
    95 |

    If you know that a user would prefer one of our alternative language translations (currently Spanish or French), you can include the locale parameter to specify the language Login.gov should use (either ES for Spanish or FR for French), e.g.:

    96 |

    https://idp.int.identitysandbox.gov/api/saml/auth2023?SAMLRequest=${SAML_REQUEST}&locale=es

    97 |
    98 |
    99 |
    100 |
    101 |
    102 |
    103 | 104 | 105 |
    106 | {% include snippets/saml/auth/request.md %} 107 |
    108 | 111 |
    112 |
    113 |
    114 |
    115 |
    116 |

    Authentication response

    117 |

    After the user authenticates, Login.gov will redirect and POST a form back to your registered Assertion Consumer Service URL:

    118 |

    The SAMLResponse is a base64-encoded XML payload that contains encrypted data.

    119 | Next step: Logout 120 |
    121 |
    122 |
    123 | 124 | 125 |
    126 | {% include snippets/saml/auth/response.md %} 127 |
    128 | 131 |
    132 |
    133 | Next step: Logout 134 |
    135 | 136 | 137 | -------------------------------------------------------------------------------- /_pages/saml/getting-started.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: SAML developer guide 3 | lead: > 4 | Login.gov is a standard SAML identity provider, adhering to the [Web Browser SSO Profile](https://en.wikipedia.org/wiki/SAML_2.0#Web_browser_SSO_profile){:class="usa-link--external"} with enhancements for [NIST 800-63-3](https://pages.nist.gov/800-63-3/){:class="usa-link--external"}. 5 | redirect_from: 6 | - /configuring-your-sp/ 7 | - /saml/ 8 | sidenav: 9 | - text: Getting started 10 | href: "/saml/getting-started/" 11 | links: 12 | - text: Configuration 13 | href: "/saml/getting-started/#configuration" 14 | - text: Metadata 15 | href: "/saml/getting-started/#metadata" 16 | - text: Signing Certificates 17 | href: "/saml/getting-started/#signing-certificates" 18 | - text: Annual Certificate Rotation 19 | href: "/saml/getting-started/#annual-certificate-rotation" 20 | - text: Example application 21 | href: "/saml/getting-started/#example-application" 22 | - text: Authentication 23 | href: "/saml/authentication/" 24 | - text: Logout 25 | href: "/saml/logout/" 26 | --- 27 | {% capture nameid %} 28 | The NameID is the unique identifier used to identify a user across multiple sessions. The format is the standard v4 random UUID (Universally Unique Identifier) in compliance with [RFC 4122](https://tools.ietf.org/html/rfc4122){:class="usa-link--external"}. 29 | 30 | For example: 31 | `urn:oasis:names:tc:SAML:2.0:nameid-format:persistent` 32 | {% endcapture %} 33 | 34 | {% capture login %} 35 | This is the endpoint where authentication requests are sent to Login.gov (aka Single Sign-on Service). 36 | 37 | For example: 38 | `` 39 | {% endcapture %} 40 | 41 | {% capture logout %} 42 | The single logout service URL is used to contact the Single logout profile (aka Single Logout Service). 43 | 44 | For example: 45 | `` 46 | {% endcapture %} 47 | 48 | {% capture saml_warning %} 49 | We strongly recommend choosing [OpenID Connect]({{site.baseurl}}/oidc/getting-started/) (OIDC) over SAML due to its modern, API-centric design and support for native mobile applications. 50 | {% endcapture %} 51 | {% include alert.html content=saml_warning alert_class="usa-alert--warning" %} 52 | 53 |
    54 |
    55 | 56 | ## Getting started 57 | 58 | SAML is an established standard, but can be a bit complex. We recommend looking for and using a SAML library for your language before developing your own. 59 | 60 | ### Configuration 61 | 62 | Here are values needed to configure your service provider (SP) to work with Login.gov: 63 | 64 |
    65 |
    66 |
    67 |

    NameID Format

    68 |
    69 |
    70 | {{ nameid | markdownify }} 71 |
    72 |
    73 |
    74 |
    75 |
    76 |
    77 |

    Login service URL and Binding

    78 |
    79 |
    80 | {{ login | markdownify }} 81 |
    82 |
    83 |
    84 |
    85 |
    86 |
    87 |

    Logout service URL and Binding

    88 |
    89 |
    90 | {{ logout | markdownify}} 91 |
    92 |
    93 |
    94 | 95 | ### x509 Public Certificate 96 | The public certificate is used to validate the authenticity of SAML requests received from Login.gov, a minimum of 2048 bits. We publish this public certificate from our [metadata endpoint](#metadata) and below for verification. 97 | 98 | ### Metadata 99 | 100 | Consistent with the [SAML metadata specification](https://docs.oasis-open.org/security/saml/v2.0/saml-metadata-2.0-os.pdf){:class="usa-link--external"}, Login.gov's metadata for our sandbox environment is available at [https://idp.int.identitysandbox.gov/api/saml/metadata{{ site.data.saml.year.current }}](https://idp.int.identitysandbox.gov/api/saml/metadata{{ site.data.saml.year.current }}). 101 | 102 | ### Signing Certificates 103 | Below you can find the X509 certificates used by the Login.gov IdP to sign SAML requests. **Do not enter these certificates in the Portal when configuring an application for testing** - you can follow the instructions in our [testing article]({% link _pages/testing.md %}#creating-a-public-certificate) to generate a client certificate. 104 | 105 |
    106 | 109 |
    110 | ``` 111 | {{ site.data.saml.certs.sandbox }} 112 | ``` 113 |
    114 |
    115 | 116 |
    117 | 120 |
    121 | ``` 122 | {{ site.data.saml.certs.production }} 123 | ``` 124 |
    125 |
    126 | 127 | #### Annual Certificate Rotation 128 | 129 | The Login.gov SAML certificate is valid for just over one year. Every spring, Login.gov adds new SAML endpoints with the current year that use a new signing certificate. 130 | 131 | - `/api/saml/auth{{ site.data.saml.year.previous }}` becomes `/api/saml/auth{{ site.data.saml.year.current }}` 132 | - `/api/saml/logout{{ site.data.saml.year.previous }}` becomes `/api/saml/logout{{ site.data.saml.year.current }}` 133 | 134 | The certificates are issued to create an overlap period of about a month, during which all partners using SAML should migrate at their convenience to the new endpoint URLs for the current year. 135 | 136 | The {{ site.data.saml.year.previous }} certificates for idp.int.identitysandbox.gov and secure.login.gov each expire on April 1, {{ site.data.saml.year.current }}. So the transition from {{ site.data.saml.year.previous }} to {{ site.data.saml.year.current }} endpoints should take place in February or March {{ site.data.saml.year.current }}. 137 | 138 | #### Example application 139 | 140 | The Login.gov team has created an example client to speed up your development, all open source in the public domain: [identity-saml-sinatra](https://github.com/18F/identity-saml-sinatra){:class="usa-link--external"}. 141 | 142 | [Next step: Authentication]({{ '/saml/authentication/' | prepend: site.baseurl }}) 143 | 144 |
    145 |
    146 | -------------------------------------------------------------------------------- /_pages/saml/logout.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: SAML developer guide 3 | lead: > 4 | Login.gov is a standard SAML identity provider, adhering to the [Web Browser SSO Profile](https://en.wikipedia.org/wiki/SAML_2.0#Web_browser_SSO_profile){:class="usa-link--external"} with enhancements for [NIST 800-63-3](https://pages.nist.gov/800-63-3/){:class="usa-link--external"}. 5 | redirect_from: 6 | - /configuring-your-sp/ 7 | sidenav: 8 | - text: Getting started 9 | href: "/saml/getting-started/" 10 | - text: Authentication 11 | href: "/saml/authentication/" 12 | - text: Logout 13 | href: "/saml/logout/" 14 | links: 15 | - text: Logout request 16 | href: "/saml/logout/#logout-request" 17 | - text: Logout response 18 | href: "/saml/logout/#logout-response" 19 | --- 20 |
    21 |
    22 | 23 | ## Logout 24 | 25 | ### Logout request 26 | 27 | Login.gov does not support Single Logout (SLO). The logout action will terminate the user's session at Login.gov but will not end any other potentially active sessions within service provider applications. For example, if a user signs in to applications A and B through Login.gov, a logout request from A will end their Login.gov session, but will not affect the session in application B. 28 | 29 | To log a user out, direct them to the logout URL with a `SAMLRequest`: 30 | 31 | The `SAMLRequest` parameter is a base64-encoded, deflate-compressed XML payload of a ``. 32 | 33 | All logout requests must be signed — we require RSA SHA-256 signatures embedded with logout requests. 34 |
    35 |
    36 |
    37 | 38 | 39 |
    40 | {% include snippets/saml/logout/request.md %} 41 |
    42 | 45 |
    46 |
    47 |
    48 |
    49 |
    50 | 51 | ### Logout response 52 | 53 | After, Login.gov will redirect and POST a form back to your registered Assertion Consumer Service Logout URL: 54 | 55 | Note: the SAMLResponse does not contain a signature since it's simply acknowledging the logout request. 56 | 57 | 58 |
    59 | 62 |
    63 | {% include snippets/saml/logout/remote_logout.md %} 64 |
    65 |
    66 |
    67 |
    68 |
    69 | 70 | 71 |
    72 | {% include snippets/saml/logout/response.md %} 73 |
    74 | 77 |
    78 |
    79 | -------------------------------------------------------------------------------- /_pages/user-experience/agency-logo.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: User Experience 3 | lead: > 4 | Create a simple and consistent experience for your Login.gov users 5 | sidenav: 6 | - text: Getting started 7 | href: "user-experience/getting-started/" 8 | - text: Sign-in and sign-out buttons 9 | href: "user-experience/sign-in-sign-out/" 10 | - text: Help text guidance 11 | href: "user-experience/help-text/" 12 | - text: Your agency logo 13 | href: "user-experience/agency-logo/" 14 | links: 15 | - text: Agency logo specifications 16 | href: "user-experience/agency-logo/#agency-logo-specifications" 17 | - text: Cancel URL 18 | href: "user-experience/cancel-url/" 19 | - text: Failure to proof URL 20 | href: "user-experience/failure-proof/" 21 | - text: Knowledge articles 22 | href: "user-experience/knowledge-articles/" 23 | - text: FAQ content 24 | href: "user-experience/faq-content/" 25 | 26 | --- 27 | 28 | ## Add your agency logo 29 | 30 | All applications are required to add a logo, which is uploaded in the Partner Portal. 31 | 32 | Your agency logo will appear to the right of the Login.gov logo in your integration. This helps to ensure users understand the partnership between Login.gov and your integration with our service. 33 | 34 | {% capture do_content %} 35 | 36 | DO: Add a logo that is high contrast on a transparent background. 37 | 38 | {% endcapture %} 39 | 40 | {% capture dont_content %} 41 | 42 | DON'T: Add a background color behind your logo. 43 | 44 | {% endcapture %} 45 | 46 |
    47 |
    48 |
    49 | An example agency logo in black on a white background 50 |
    51 |
      52 |
    • 53 | {% include icon_list.html icon_name="check_circle" style="text-success" content=do_content %} 54 |
    • 55 |
    56 |
    57 |
    58 |
    59 |
    60 |
    61 | An example agency logo in grey on a light grey background 62 |
    63 |
      64 |
    • 65 | {% include icon_list.html icon_name="cancel" style="text-error" content=dont_content %} 66 |
    • 67 |
    68 |
    69 |
    70 |
    71 |
    72 | 73 | ### Agency logo specifications 74 | 75 |
      76 |
    • 77 | {% include icon_list.html icon_name="check_circle" content="Upload a logo that is high contrast on a transparent background" style="text-success" %} 78 |
    • 79 |
    • 80 | {% include icon_list.html icon_name="check_circle" content="Both .svg and .png files up to 50 kB are accepted" style="text-success" %} 81 |
    • 82 |
    83 | 84 | [Next step: Determine your application’s Cancel URL]({{ site.baseurl }}/user-experience/cancel-url/) 85 | -------------------------------------------------------------------------------- /_pages/user-experience/cancel-url.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: User Experience 3 | lead: > 4 | Create a simple and consistent experience for your Login.gov users 5 | sidenav: 6 | - text: Getting started 7 | href: "user-experience/getting-started/" 8 | - text: Sign-in and sign-out buttons 9 | href: "user-experience/sign-in-sign-out/" 10 | - text: Help text guidance 11 | href: "user-experience/help-text/" 12 | - text: Your agency logo 13 | href: "user-experience/agency-logo/" 14 | - text: Cancel URL 15 | href: "user-experience/cancel-url/" 16 | links: 17 | - text: OIDC Redirect URI 18 | href: "#oidc-redirect-uri" 19 | - text: SAML Return to SP URL 20 | href: "#saml-return-to-sp-url" 21 | - text: Failure to proof URL 22 | href: "user-experience/failure-proof/" 23 | - text: Knowledge articles 24 | href: "user-experience/knowledge-articles/" 25 | - text: FAQ content 26 | href: "user-experience/faq-content/" 27 | 28 | --- 29 | 30 | ## Determine your application’s return to service provider URL 31 | 32 | When a user does not authenticate successfully, they should be returned to the service provider application to restart the authentication process. It is important that the user returns to a familiar site and that they have a clear path back to the authentication workflow. 33 | 34 | Depending on the type of integration (OIDC or SAML) you will need to set the `redirect_uri` or the `return_to_sp_url`. 35 | 36 | ### OIDC Redirect URI: 37 | 38 | Your integration should include a redirect URI for successful authentication attempts and canceled authentication attempts. Ideally, the user will be returned to the app site or the Login.gov form and can restart the authentication process. The URIs can be public, internal, or localhost, or a custom scheme to support native applications, for example: `gov.agency.app://result`. 39 | 40 | ### SAML Return to SP URL: 41 | 42 | This URL will be used if a user chooses to cancel out of the authentication workflow or return to the app site. For example, users would be returned to: `https://app.agency.gov`. 43 | 44 | [Next step: For Identity Verification permitted applications, determine your application’s failure to proof URL]({{ site.baseurl }}/user-experience/failure-proof/) 45 | -------------------------------------------------------------------------------- /_pages/user-experience/failure-proof.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: User Experience 3 | lead: > 4 | Create a simple and consistent experience for your Login.gov users 5 | sidenav: 6 | - text: Getting started 7 | href: "user-experience/getting-started/" 8 | - text: Sign-in and sign-out buttons 9 | href: "user-experience/sign-in-sign-out/" 10 | - text: Help text guidance 11 | href: "user-experience/help-text/" 12 | - text: Your agency logo 13 | href: "user-experience/agency-logo/" 14 | - text: Cancel URL 15 | href: "user-experience/cancel-url/" 16 | - text: Failure to proof URL 17 | href: "user-experience/failure-proof/" 18 | links: 19 | - text: What is a Failure to Proof URL? 20 | href: "user-experience/failure-proof/#what-is-a-failure-to-proof-url" 21 | - text: Where should the Failure to Proof URL take users? 22 | href: "user-experience/failure-proof/#where-should-the-failure-to-proof-url-take-users" 23 | - text: Knowledge articles 24 | href: "user-experience/knowledge-articles/" 25 | - text: FAQ content 26 | href: "user-experience/faq-content/" 27 | 28 | --- 29 | 30 | ## Identity Verification: Create a Failure to Proof URL 31 | Applications with Login.gov identity verification need to provide an alternative proofing path to support users who are unable to complete Login.gov’s process. 32 | 33 | ### What is a Failure to Proof URL? 34 | Login.gov’s agency partners provide a link that their users are directed to if they are unable to verify their identity with Login.gov. This is called the Failure to Proof URL (e.g. `failure_to_proof_url`). This link routes users to a designated page on the agency partner’s site which is configured as part of the agency's integration. 35 | 36 | The Failure to Proof URL is shown to users throughout the identity proofing process. Some examples of when a user might encounter this are: 37 | 38 | - Users might navigate to this page if they don’t have a valid state-issued ID or Social Security number. 39 | - The Failure to Proof URL is available for users who are not able to capture or upload photos of their ID. 40 | - Users see the Failure to Proof URL when they encounter errors verifying their ID, personal information, or phone number. Examples of this include: 41 | - Users who enter valid information, but are not able to pass Login.gov’s proofing process because we cannot verify their information. 42 | - Users who have run out of attempts to verify their information. 43 | 44 | ### Where should the Failure to Proof URL take users? 45 | 46 | The purpose of the Failure to Proof URL is to provide an actionable next step for users who do not have the required information to complete remote identity verification or otherwise cannot pass the process through Login.gov. The agency’s designated destination page should include instructions for users on what to do to access the agency partner’s services. 47 | 48 | Want to discuss options for your Failure to Proof URL? 53 | Contact us 54 | 55 | 56 | [Next step: Create knowledge articles for Login.gov customer support]({{ site.baseurl }}/user-experience/knowledge-articles/) 57 | -------------------------------------------------------------------------------- /_pages/user-experience/faq-content.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: User Experience 3 | lead: > 4 | Create a simple and consistent experience for your Login.gov users 5 | sidenav: 6 | - text: Getting started 7 | href: "user-experience/getting-started/" 8 | - text: Sign-in and sign-out buttons 9 | href: "user-experience/sign-in-sign-out/" 10 | - text: Help text guidance 11 | href: "user-experience/help-text/" 12 | - text: Your agency logo 13 | href: "user-experience/agency-logo/" 14 | - text: Cancel URL 15 | href: "user-experience/cancel-url/" 16 | - text: Failure to proof URL 17 | href: "user-experience/failure-proof/" 18 | - text: Knowledge articles 19 | href: "user-experience/knowledge-articles/" 20 | - text: FAQ content 21 | href: "user-experience/faq-content/" 22 | 23 | --- 24 | 25 | ## Add FAQ content to inform users about Login.gov (Optional) 26 | 27 | When you first integrate with Login.gov, we recommend adding frequently asked questions (FAQ) content to ensure that users are able to understand that your application uses Login.gov as a sign-in service. The next few sections outline plain language for agencies to leverage when creating that content. 28 | 29 | ### What is Login.gov? 30 | Login.gov is a sign in service that offers secure and private online access to government programs, such as federal benefits, services and applications. With a Login.gov account, you can sign in to multiple government websites with the same email address and password. [Learn more about Login.gov](https://login.gov/). 31 | 32 | ### Why is [YOUR APPLICATION] using Login.gov? 33 | [APPLICATION] chose Login.gov as their sign-in provider as a security measure. This service requires you to use an email address, password and two-factor authentication, sometimes referred to as multi-factor authentication, to sign-in. The use of two-factor authentication is an added layer of security to protect your private and sensitive information from hackers and password compromises. 34 | 35 | **[Identity Verification ONLY]** In addition to meeting the above requirements for multi-factor authentication, Login.gov asks users to upload a photograph of their state-issued ID and share their address, phone number and other personal information which is then verified against authoritative sources. Verifying your identity makes sure the right person has access to the right information. We are using Login.gov’s simple and secure process to keep your sensitive information safe. 36 | 37 | ### How do I create a Login.gov account? 38 | Start by selecting sign-in on [APPLICATION home page or link]. You’ll automatically be taken to the Login.gov sign-in page. You can create an account or sign in if you already have a Login.gov account. Login.gov is only the sign-in service. Once you sign in, you’ll be directed to your [APPLICATION] account or profile. 39 | 40 | Login.gov requires you to use a multifactor authentication method. You can select to receive a code via SMS/Text or phone call or use an authentication application, government PIV/CAC card, face or touch unlock, security key or download backup codes. We encourage you to add more than one authentication method to your account to avoid getting locked out if you ever lose an authentication method. Learn more about the different authentication methods you can use. 46 | 47 | ### How do I sign in to [APPLICATION] after I create my Login.gov account? 48 | Every time you click on Sign In on the APPLICATION site, you’ll go to the Login.gov sign in page. Enter your Login.gov email address, password and use your two-factor authentication method. Once you enter this information correctly, you’ll be signed in and automatically directed back to the APPLICATION site. 49 | 50 | ### Can I use my existing [APPLICATION] username and password to sign in? 51 | No. Your old username and password will no longer work. You must create a new account or use your existing Login.gov account to sign in. We’ll connect your new Login.gov account with your existing [APPLICATION] profile during the process. 52 | 53 | ### What if I already have a Login.gov account? 54 | If you already have a Login.gov account, you don’t need to create a second one. Use your existing Login.gov email address, password and a two-factor authentication method to sign in to [APPLICATION]. 55 | 56 | ### What email address do I use to create a Login.gov account? 57 | If you don’t have an [APPLICATION] profile, we recommend you use a personal email address that you control. We recommend you don’t use a work email address. Why? If you leave your job, you’ll no longer have access to that email address. Without access to that email address, it will be much harder to verify who you are, if you ever need to reset your password. You also can’t use an email address you share with someone else. 58 | 59 | ### Can I share a Login.gov account with another person? 60 | No. Each person must set up their own Login.gov account, with their own personal email address (not an email that you share with someone else). 61 | 62 | ### Where do I get support for my Login.gov account? 63 | Login.gov can only help you resolve issues around signing in. For example, you would contact Login.gov if you have questions about your password or two-factor authentication method. 64 | 65 | Please keep in mind Login.gov cannot reset, delete or access your account on your behalf if you are locked out. You’ll need to delete your account and start again. 66 | 67 | We encourage you to add more than one two-factor authentication method and to keep your username and password in a safe place. Visit the Login.gov Help center to learn more. 73 | 74 | ### Can Login.gov help me with my [APPLICATION] benefits, services, application or profile? 75 | No. You still need to contact [AGENCY] for questions about your [APPLICATION] benefits, services, application or profile. [IF APPLICABLE] Our customer support can be reached [info]. 76 | 77 | -------------------------------------------------------------------------------- /_pages/user-experience/getting-started.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: User Experience 3 | lead: > 4 | Create a simple and consistent experience for your Login.gov users 5 | redirect_from: 6 | - /user-experience/ 7 | - /design-guidelines/ 8 | sidenav: 9 | - text: Getting started 10 | href: "user-experience/getting-started/" 11 | - text: Sign-in and sign-out buttons 12 | href: "user-experience/sign-in-sign-out/" 13 | - text: Help text guidance 14 | href: "user-experience/help-text/" 15 | - text: Your agency logo 16 | href: "user-experience/agency-logo/" 17 | - text: Cancel URL 18 | href: "user-experience/cancel-url/" 19 | - text: Failure to proof URL 20 | href: "user-experience/failure-proof/" 21 | - text: Knowledge articles 22 | href: "user-experience/knowledge-articles/" 23 | - text: FAQ content 24 | href: "user-experience/faq-content/" 25 | 26 | --- 27 | 28 | ## Getting started 29 | There are several decisions during the integration process that affect how your users experience Login.gov. In this User Experience guide, we will outline what options you have available to your application, and the configurations in Login.gov [portal](https://dashboard.int.identitysandbox.gov/) that impact users. 30 | 31 | {% capture button_ux %} 32 | [Design your application's sign-in and sign-out buttons]({{site.baseurl}}/user-experience/sign-in-sign-out/). This will include a [global sign-in button]({{site.baseurl}}/user-experience/sign-in-sign-out/), and optionally, [a sign-in page]({{site.baseurl}}/user-experience/sign-in-sign-out/) before the user is directed to Login.gov. 33 | {% endcapture %} 34 | 35 | {% capture failure_to_proof_ux %} 36 | All partners with identity verification will [create a Failure to Proof URL]({{site.baseurl}}/user-experience/failure-proof/) for users who cannot pass identity proofing with Login.gov. This URL is configured in the sandbox portal, but may require designing a new page or process on your agency's website or application. 37 | {% endcapture %} 38 | 39 | {% capture link_to_helpdesk %} 40 | Include a link to the [self-service Login.gov help center](https://login.gov/help/). (Do not publish the help center phone number on your application.) 41 | {% endcapture %} 42 | 43 | {% capture faq_ux %} 44 | Optional: [Add FAQ content to inform users about Login.gov]({{site.baseurl}}/user-experience/faq-content/) 45 | {% endcapture %} 46 | 47 | {% capture logo_ux %} 48 | [Add your agency logo]({{site.baseurl}}/user-experience/agency-logo/) to help users understand the partnership between Login.gov and your agency. 49 | {% endcapture %} 50 | 51 | {% capture cancel_url_ux %} 52 | [Determine your application’s Cancel URL]({{site.baseurl}}/user-experience/cancel-url/) 53 | {% endcapture %} 54 | 55 | {% capture dashboard_failure_to_proof %} 56 | [Identity Verification: Create a Failure to Proof URL]({{site.baseurl}}/user-experience/failure-proof/) 57 | {% endcapture %} 58 | 59 | 60 | ### Add to your agency's application 61 | 62 |
      63 |
    • 64 | {% include icon_list.html icon_name="check_circle" content=button_ux style="text-success" %} 65 |
    • 66 |
    • 67 | {% include icon_list.html icon_name="check_circle" content=failure_to_proof_ux style="text-success" %} 68 |
    • 69 |
    • 70 | {% include icon_list.html icon_name="check_circle" content=link_to_helpdesk style="text-success" %} 71 |
    • 72 |
    • 73 | {% include icon_list.html icon_name="check_circle" content=faq_ux style="text-success" %} 74 |
    • 75 |
    76 | 77 | ### Configure in the [portal](https://dashboard.int.identitysandbox.gov/) 78 | 79 |
      80 |
    • 81 | {% include icon_list.html icon_name="check_circle" content=logo_ux style="text-success" %} 82 |
    • 83 |
    • 84 | {% include icon_list.html icon_name="check_circle" content=cancel_url_ux style="text-success" %} 85 |
    • 86 |
    • 87 | {% include icon_list.html icon_name="check_circle" content=dashboard_failure_to_proof style="text-success" %} 88 |
    • 89 |
    90 | 91 | [Next step: Design your application's sign-in and sign-out buttons]({{site.baseurl}}/user-experience/sign-in-sign-out/) 92 | 93 | -------------------------------------------------------------------------------- /_pages/user-experience/help-text.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: User Experience 3 | lead: > 4 | Create a simple and consistent experience for your Login.gov users 5 | sidenav: 6 | - text: Getting started 7 | href: "user-experience/getting-started/" 8 | - text: Sign-in and sign-out buttons 9 | href: "user-experience/sign-in-sign-out/" 10 | - text: Help text guidance 11 | href: "user-experience/help-text/" 12 | - text: Your agency logo 13 | href: "user-experience/agency-logo/" 14 | - text: Cancel URL 15 | href: "user-experience/cancel-url/" 16 | - text: Failure to proof URL 17 | href: "user-experience/failure-proof/" 18 | - text: Knowledge articles 19 | href: "user-experience/knowledge-articles/" 20 | - text: FAQ content 21 | href: "user-experience/faq-content/" 22 | 23 | --- 24 | 25 | ## Help text guidance 26 | 27 | You may include help text to alert the users to specific information that will assist them in logging in, signing up, and logging out. The help text section of the app configuration workflow allows you to choose from the default help text options or request custom help text specific to your integration. 28 | 29 | Custom help text should follow the guidelines below to be included in your integration: 30 | 31 | 32 |
      33 |
    • 34 | {% include icon_list.html icon_name="check_circle" content="Help text should be brief, specific, and useful. It should add to the information already displayed on the page." style="text-success" %} 35 |
    • 36 |
    • 37 | {% include icon_list.html icon_name="check_circle" content="Include agency-specific contact information if needed." style="text-success" %} 38 |
    • 39 |
    • 40 | {% include icon_list.html icon_name="check_circle" content="Include Spanish and French translations of your custom help text." style="text-success" %} 41 |
    • 42 |
    • 43 | {% include icon_list.html icon_name="cancel" style="text-error" content="Repeat general instructions to complete the process (eg Sign in here)." %} 44 |
    • 45 |
    • 46 | {% include icon_list.html icon_name="cancel" style="text-error" content="Include legal disclaimers. These should be displayed on a separate page." %} 47 |
    • 48 |
    • 49 | {% include icon_list.html icon_name="cancel" style="text-error" content="Use link text like “click here” or “learn more”. Link text should be descriptive and inform the user what they are linking to." %} 50 |
    • 51 |
    52 | 53 | 54 | To request custom help text, reach out to the [Partner Support Help Desk](https://zendesk.login.gov/). 55 | 56 | [Next step: Add your agency logo]({{ site.baseurl }}/user-experience/agency-logo/) -------------------------------------------------------------------------------- /_pages/user-experience/knowledge-articles.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: User Experience 3 | lead: > 4 | Create a simple and consistent experience for your Login.gov users 5 | sidenav: 6 | - text: Getting started 7 | href: "user-experience/getting-started/" 8 | - text: Sign-in and sign-out buttons 9 | href: "user-experience/sign-in-sign-out/" 10 | - text: Help text guidance 11 | href: "user-experience/help-text/" 12 | - text: Your agency logo 13 | href: "user-experience/agency-logo/" 14 | - text: Cancel URL 15 | href: "user-experience/cancel-url/" 16 | - text: Failure to proof URL 17 | href: "user-experience/failure-proof/" 18 | - text: Knowledge articles 19 | href: "user-experience/knowledge-articles/" 20 | - text: FAQ content 21 | href: "user-experience/faq-content/" 22 | 23 | --- 24 | 25 | ## Prepare customer support materials 26 | 27 | As you prepare to launch your integration with Login.gov, it is important to consider how your agency will support new users. Here are some suggestions to consider: 28 | 29 | - Announce the upcoming change on your site and include a time frame rather than exact date. 30 | - Link to the [Create an account](https://www.login.gov/create-an-account/){:class="usa-link--external" rel="noreferrer" target="_blank"} page at Login.gov so users can read more about creating an account. 31 | - Include contact information for your help desk or a link to the Login.gov help center () on a dedicated help page. 32 | - Be sure to communicate the go-live date with the Login.gov customer support center so agents are prepared for a spike in new account creation support cases. 33 | 34 | Some partners have created knowledge base articles that they post on their website, send to users directly by the agency’s customer support team, or forward to the Login.gov customer support team. These can be especially helpful if your integration includes any additional authentication steps on your agency's side. Here are some topics for knowledge articles: 35 | 36 | - A brief step-by-step guide to the Login.gov authentication process and the identity verification (IdV) if your agency supports IdV. 37 | - Short description of each requirement in the authentication process, e.g., multi-factor authentication or using a unique email. 38 | - Which support topics should the user contact your agency for help with vs. Login.gov. 39 | - If existing users will need to create a new account or if they will be able to link their agency account to the Login.gov account. 40 | 41 | The Login.gov customer support team can assist users with account creation questions, but they cannot support any agency-specific issues. It is important that users are able to find correct and timely help. Consider including a few support examples along with the link to the Login.gov help center (https://www.login.gov/help/). 42 | 43 | For example: 44 | 45 | {% capture example %} 46 | **Contact Login.gov to:** 47 | - Help you create a Login.gov account 48 | - Share information about authentication options 49 | - Help you troubleshoot why you are unable to access your account 50 | - Provide instructions to reset your password or delete your account 51 | 52 | Login.gov cannot reset your password, delete your account, or change your account information. 53 | 54 | **Contact the agency partner to:** 55 | - Perform agency specific tasks, like uploading your resume, completing applications or scheduling an appointment with that agency 56 | - Resolve technical issues with a partner agency website 57 | - Access your personal agency specific information such as application status, services, eligibility or payments 58 | {% endcapture %} 59 | 60 |
    61 | {{ example | markdownify }} 62 |
    63 | 64 | [Next step: Create FAQ content]({{ site.baseurl }}/user-experience/faq-content/) 65 | -------------------------------------------------------------------------------- /_plugins/content_code.rb: -------------------------------------------------------------------------------- 1 | require 'rouge' 2 | 3 | # Include tabindex for accessibility reasons 4 | # See: https://github.com/rouge-ruby/rouge?tab=readme-ov-file#formatters 5 | class Rouge::Formatters::HTMLPygmentsA11y < Rouge::Formatters::HTMLPygments 6 | def stream(tokens, &b) 7 | yield %(
    )
     8 |     @inner.stream(tokens, &b)
     9 |     yield "
    " 10 | end 11 | end 12 | 13 | class Rouge::Formatters::HTMLLegacyA11y < Rouge::Formatters::HTMLLegacy 14 | def initialize(opts={}) 15 | @formatter = opts[:inline_theme] ? Rouge::Formatters::HTMLInline.new(opts[:inline_theme]) 16 | : Rouge::Formatters::HTML.new 17 | 18 | 19 | @formatter = Rouge::Formatters::HTMLTable.new(@formatter, opts) if opts[:line_numbers] 20 | 21 | if opts.fetch(:wrap, true) 22 | @formatter = Rouge::Formatters::HTMLPygmentsA11y.new(@formatter, opts.fetch(:css_class, 'codehilite')) 23 | end 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /_plugins/content_typography.rb: -------------------------------------------------------------------------------- 1 | module Kramdown 2 | module Parser 3 | class Kramdown 4 | prepend(Module.new do 5 | def add_link(el, *args) 6 | add_link_class!(el) if el.type == :a 7 | super(el, *args) 8 | end 9 | 10 | def parse_autolink 11 | *children, el = super 12 | add_link_class!(el) 13 | [*children, el] 14 | end 15 | 16 | def add_link_class!(el) 17 | el.attr['class'] = [*el.attr['class'], 'usa-link'].join(' ') 18 | end 19 | end) 20 | end 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /_plugins/copy_to_destination.rb: -------------------------------------------------------------------------------- 1 | module Jekyll 2 | module CopyToDestination 3 | class CopyGenerator < Generator 4 | def generate(site) 5 | folders = site.config['copy_to_destination'] || [] 6 | 7 | static_files = folders.map do |relative_path| 8 | absolute_path = File.join(site.source, relative_path) 9 | folder_path = File.dirname(absolute_path) 10 | entries = Dir.glob(File.join(absolute_path, '**', '*')) 11 | files = entries.select { |f| File.file?(f) } 12 | 13 | files.map do |file| 14 | relative_directory = File.dirname(file).sub(folder_path, '') 15 | filename = File.basename(file) 16 | StaticFile.new(site, folder_path, relative_directory, filename) 17 | end 18 | end.flatten 19 | 20 | site.static_files.concat(static_files) 21 | end 22 | end 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /_plugins/pretty_jsonify.rb: -------------------------------------------------------------------------------- 1 | require 'json' 2 | 3 | module LoginGov 4 | module PrettyJsonify 5 | def pretty_jsonify(input) 6 | json = if input.kind_of?(String) 7 | JSON.parse(input) 8 | else 9 | json 10 | end 11 | 12 | JSON.pretty_generate(json) 13 | end 14 | end 15 | end 16 | 17 | Liquid::Template.register_filter(LoginGov::PrettyJsonify) 18 | -------------------------------------------------------------------------------- /_plugins/yaml_content_disposition.rb: -------------------------------------------------------------------------------- 1 | require 'webrick' 2 | 3 | module Jekyll 4 | module Commands 5 | class Serve 6 | class Servlet < WEBrick::HTTPServlet::FileHandler 7 | prepend(Module.new do 8 | def do_GET(req, res) 9 | res.header.merge!('Content-Disposition' => 'attachment') if req.path.end_with?('.yml') 10 | super 11 | end 12 | end) 13 | end 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /assets/img/agency-logo-contrast.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GSA-TTS/identity-dev-docs/d4f66a8128ae2ab40dfa619bd34d74cd0a9d332a/assets/img/agency-logo-contrast.png -------------------------------------------------------------------------------- /assets/img/dashboard_issuer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GSA-TTS/identity-dev-docs/d4f66a8128ae2ab40dfa619bd34d74cd0a9d332a/assets/img/dashboard_issuer.png -------------------------------------------------------------------------------- /assets/img/do_logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /assets/img/dont_logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /assets/img/global-sign-in.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GSA-TTS/identity-dev-docs/d4f66a8128ae2ab40dfa619bd34d74cd0a9d332a/assets/img/global-sign-in.png -------------------------------------------------------------------------------- /assets/img/icon-system-status.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/img/logo-guidelines.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GSA-TTS/identity-dev-docs/d4f66a8128ae2ab40dfa619bd34d74cd0a9d332a/assets/img/logo-guidelines.png -------------------------------------------------------------------------------- /assets/img/logo-white.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/img/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/img/oidc-auth-flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GSA-TTS/identity-dev-docs/d4f66a8128ae2ab40dfa619bd34d74cd0a9d332a/assets/img/oidc-auth-flow.png -------------------------------------------------------------------------------- /assets/img/oidc-ial1-flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GSA-TTS/identity-dev-docs/d4f66a8128ae2ab40dfa619bd34d74cd0a9d332a/assets/img/oidc-ial1-flow.png -------------------------------------------------------------------------------- /assets/img/oidc-ial2-flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GSA-TTS/identity-dev-docs/d4f66a8128ae2ab40dfa619bd34d74cd0a9d332a/assets/img/oidc-ial2-flow.png -------------------------------------------------------------------------------- /assets/img/sign-out-button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GSA-TTS/identity-dev-docs/d4f66a8128ae2ab40dfa619bd34d74cd0a9d332a/assets/img/sign-out-button.png -------------------------------------------------------------------------------- /assets/img/sign-out-menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GSA-TTS/identity-dev-docs/d4f66a8128ae2ab40dfa619bd34d74cd0a9d332a/assets/img/sign-out-menu.png -------------------------------------------------------------------------------- /assets/js/anchor.js: -------------------------------------------------------------------------------- 1 | /** 2 | * AnchorJS - v4.1.0 - 2017-09-20 3 | * https://github.com/bryanbraun/anchorjs 4 | * Copyright (c) 2017 Bryan Braun; Licensed MIT 5 | */ 6 | !function(A,e){"use strict";"function"==typeof define&&define.amd?define([],e):"object"==typeof module&&module.exports?module.exports=e():(A.AnchorJS=e(),A.anchors=new A.AnchorJS)}(this,function(){"use strict";return function(A){function e(A){A.icon=A.hasOwnProperty("icon")?A.icon:"",A.visible=A.hasOwnProperty("visible")?A.visible:"hover",A.placement=A.hasOwnProperty("placement")?A.placement:"right",A.ariaLabel=A.hasOwnProperty("ariaLabel")?A.ariaLabel:"Anchor",A.class=A.hasOwnProperty("class")?A.class:"",A.truncate=A.hasOwnProperty("truncate")?Math.floor(A.truncate):64}function t(A){var e;if("string"==typeof A||A instanceof String)e=[].slice.call(document.querySelectorAll(A));else{if(!(Array.isArray(A)||A instanceof NodeList))throw new Error("The selector provided to AnchorJS was invalid.");e=[].slice.call(A)}return e}function i(){if(null===document.head.querySelector("style.anchorjs")){var A,e=document.createElement("style");e.className="anchorjs",e.appendChild(document.createTextNode("")),void 0===(A=document.head.querySelector('[rel="stylesheet"], style'))?document.head.appendChild(e):document.head.insertBefore(e,A),e.sheet.insertRule(" .anchorjs-link { opacity: 0; text-decoration: none; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }",e.sheet.cssRules.length),e.sheet.insertRule(" *:hover > .anchorjs-link, .anchorjs-link:focus { opacity: 1; }",e.sheet.cssRules.length),e.sheet.insertRule(" [data-anchorjs-icon]::after { content: attr(data-anchorjs-icon); }",e.sheet.cssRules.length),e.sheet.insertRule(' @font-face { font-family: "anchorjs-icons"; src: url(data:n/a;base64,AAEAAAALAIAAAwAwT1MvMg8yG2cAAAE4AAAAYGNtYXDp3gC3AAABpAAAAExnYXNwAAAAEAAAA9wAAAAIZ2x5ZlQCcfwAAAH4AAABCGhlYWQHFvHyAAAAvAAAADZoaGVhBnACFwAAAPQAAAAkaG10eASAADEAAAGYAAAADGxvY2EACACEAAAB8AAAAAhtYXhwAAYAVwAAARgAAAAgbmFtZQGOH9cAAAMAAAAAunBvc3QAAwAAAAADvAAAACAAAQAAAAEAAHzE2p9fDzz1AAkEAAAAAADRecUWAAAAANQA6R8AAAAAAoACwAAAAAgAAgAAAAAAAAABAAADwP/AAAACgAAA/9MCrQABAAAAAAAAAAAAAAAAAAAAAwABAAAAAwBVAAIAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAMCQAGQAAUAAAKZAswAAACPApkCzAAAAesAMwEJAAAAAAAAAAAAAAAAAAAAARAAAAAAAAAAAAAAAAAAAAAAQAAg//0DwP/AAEADwABAAAAAAQAAAAAAAAAAAAAAIAAAAAAAAAIAAAACgAAxAAAAAwAAAAMAAAAcAAEAAwAAABwAAwABAAAAHAAEADAAAAAIAAgAAgAAACDpy//9//8AAAAg6cv//f///+EWNwADAAEAAAAAAAAAAAAAAAAACACEAAEAAAAAAAAAAAAAAAAxAAACAAQARAKAAsAAKwBUAAABIiYnJjQ3NzY2MzIWFxYUBwcGIicmNDc3NjQnJiYjIgYHBwYUFxYUBwYGIwciJicmNDc3NjIXFhQHBwYUFxYWMzI2Nzc2NCcmNDc2MhcWFAcHBgYjARQGDAUtLXoWOR8fORYtLTgKGwoKCjgaGg0gEhIgDXoaGgkJBQwHdR85Fi0tOAobCgoKOBoaDSASEiANehoaCQkKGwotLXoWOR8BMwUFLYEuehYXFxYugC44CQkKGwo4GkoaDQ0NDXoaShoKGwoFBe8XFi6ALjgJCQobCjgaShoNDQ0NehpKGgobCgoKLYEuehYXAAAADACWAAEAAAAAAAEACAAAAAEAAAAAAAIAAwAIAAEAAAAAAAMACAAAAAEAAAAAAAQACAAAAAEAAAAAAAUAAQALAAEAAAAAAAYACAAAAAMAAQQJAAEAEAAMAAMAAQQJAAIABgAcAAMAAQQJAAMAEAAMAAMAAQQJAAQAEAAMAAMAAQQJAAUAAgAiAAMAAQQJAAYAEAAMYW5jaG9yanM0MDBAAGEAbgBjAGgAbwByAGoAcwA0ADAAMABAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAH//wAP) format("truetype"); }',e.sheet.cssRules.length)}}this.options=A||{},this.elements=[],e(this.options),this.isTouchDevice=function(){return!!("ontouchstart"in window||window.DocumentTouch&&document instanceof DocumentTouch)},this.add=function(A){var n,o,s,a,r,c,h,l,u,d,f,p=[];if(e(this.options),"touch"===(f=this.options.visible)&&(f=this.isTouchDevice()?"always":"hover"),A||(A="h2, h3, h4, h5, h6"),0===(n=t(A)).length)return this;for(i(),o=document.querySelectorAll("[id]"),s=[].map.call(o,function(A){return A.id}),r=0;r\]\.\/\(\)\*\\]/g;return this.options.truncate||e(this.options),A.trim().replace(/\'/gi,"").replace(t,"-").replace(/-{2,}/g,"-").substring(0,this.options.truncate).replace(/^-+|-+$/gm,"").toLowerCase()},this.hasAnchorJSLink=function(A){var e=A.firstChild&&(" "+A.firstChild.className+" ").indexOf(" anchorjs-link ")>-1,t=A.lastChild&&(" "+A.lastChild.className+" ").indexOf(" anchorjs-link ")>-1;return e||t||!1}}}); 7 | -------------------------------------------------------------------------------- /assets/js/toggle_view.js: -------------------------------------------------------------------------------- 1 | // Elements for Listeners 2 | const oidcAuthTab1Button = document.getElementById('oidc_auth_tab1_button'); 3 | const oidcAuthTab2Button = document.getElementById('oidc_auth_tab2_button'); 4 | const oidcTokenTab1Button = document.getElementById('oidc_token_tab1_button'); 5 | const oidcTokenTab2Button = document.getElementById('oidc_token_tab2_button'); 6 | const oidcUserInfoTab1Button = document.getElementById('oidc_user-info_tab1_button'); 7 | const oidcUserInfoTab2Button = document.getElementById('oidc_user-info_tab2_button'); 8 | const oidcLogoutTab1Button = document.getElementById('oidc_logout_tab1_button'); 9 | const oidcLogoutTab2Button = document.getElementById('oidc_logout_tab2_button'); 10 | const samlAuthTab1Button = document.getElementById('saml_auth_tab1_button'); 11 | const samlAuthTab2Button = document.getElementById('saml_auth_tab2_button'); 12 | const samlAuthResponseTab1Button = document.getElementById('saml_auth_response_tab1_button'); 13 | const samlAuthResponseTab2Button = document.getElementById('saml_auth_response_tab2_button'); 14 | const samlLogoutTab1Button = document.getElementById('saml_logout_tab1_button'); 15 | const samlLogoutTab2Button = document.getElementById('saml_logout_tab2_button'); 16 | const samlLogoutResponseTab1Button = document.getElementById('saml_logout_response_tab1_button'); 17 | const samlLogoutResponseTab2Button = document.getElementById('saml_logout_response_tab2_button'); 18 | 19 | function hideTabTwoCode(evt) { 20 | const errorButton = document.getElementById(`${evt.currentTarget.dataset.selector}_tab2_button`); 21 | errorButton.classList.remove('code-button__selected'); 22 | const codeSnippet = document.getElementById(`${evt.currentTarget.dataset.selector}_tab2`); 23 | codeSnippet.hidden = true; 24 | } 25 | 26 | function hideTabOneCode(evt) { 27 | const successButton = document.getElementById( 28 | `${evt.currentTarget.dataset.selector}_tab1_button`, 29 | ); 30 | successButton.classList.remove('code-button__selected'); 31 | const codeSnippet = document.getElementById(`${evt.currentTarget.dataset.selector}_tab1`); 32 | codeSnippet.hidden = true; 33 | } 34 | 35 | function showTabOneCode(evt) { 36 | evt.currentTarget.classList.add('code-button__selected'); 37 | const codeSnippet = document.getElementById(`${evt.currentTarget.dataset.selector}_tab1`); 38 | codeSnippet.hidden = false; 39 | hideTabTwoCode(evt); 40 | } 41 | 42 | function showTabTwoCode(evt) { 43 | evt.currentTarget.classList.add('code-button__selected'); 44 | const codeSnippet = document.getElementById(`${evt.currentTarget.dataset.selector}_tab2`); 45 | codeSnippet.hidden = false; 46 | hideTabOneCode(evt); 47 | } 48 | 49 | // Event Listeners 50 | if (oidcAuthTab1Button) { 51 | oidcAuthTab1Button.addEventListener('click', showTabOneCode); 52 | oidcAuthTab2Button.addEventListener('click', showTabTwoCode); 53 | } 54 | if (oidcTokenTab1Button) { 55 | oidcTokenTab1Button.addEventListener('click', showTabOneCode); 56 | oidcTokenTab2Button.addEventListener('click', showTabTwoCode); 57 | } 58 | if (oidcUserInfoTab1Button) { 59 | oidcUserInfoTab1Button.addEventListener('click', showTabOneCode); 60 | oidcUserInfoTab2Button.addEventListener('click', showTabTwoCode); 61 | } 62 | if (oidcLogoutTab1Button) { 63 | oidcLogoutTab1Button.addEventListener('click', showTabOneCode); 64 | oidcLogoutTab2Button.addEventListener('click', showTabTwoCode); 65 | } 66 | if (samlAuthTab1Button) { 67 | samlAuthTab1Button.addEventListener('click', showTabOneCode); 68 | samlAuthTab2Button.addEventListener('click', showTabTwoCode); 69 | samlAuthResponseTab1Button.addEventListener('click', showTabOneCode); 70 | samlAuthResponseTab2Button.addEventListener('click', showTabTwoCode); 71 | } 72 | if (samlLogoutTab1Button) { 73 | samlLogoutTab1Button.addEventListener('click', showTabOneCode); 74 | samlLogoutTab2Button.addEventListener('click', showTabTwoCode); 75 | samlLogoutResponseTab1Button.addEventListener('click', showTabOneCode); 76 | samlLogoutResponseTab2Button.addEventListener('click', showTabTwoCode); 77 | } 78 | -------------------------------------------------------------------------------- /assets/scss/_footer.scss: -------------------------------------------------------------------------------- 1 | @use 'uswds-core' as *; 2 | 3 | .footer { 4 | @include u-padding(0); 5 | background-color: color('primary-lightest'); 6 | } 7 | 8 | .footer-navigation { 9 | justify-content: space-between; 10 | @include u-padding-top(2); 11 | @include u-padding-bottom(5); 12 | @include at-media('desktop') { 13 | @include u-padding-right(4); 14 | @include u-padding-left(4); 15 | } 16 | 17 | ul { 18 | @include unstyled-list; 19 | } 20 | 21 | h2, 22 | a { 23 | font-size: 0.85rem; 24 | color: color('primary-dark'); 25 | } 26 | } 27 | 28 | .footer-navigation__section h2 { 29 | margin: 0; 30 | } 31 | 32 | .footer-navigation__section a { 33 | @include u-margin-top(2); 34 | display: block; 35 | } 36 | 37 | .usa-identifier__usagov-description { 38 | @include u-margin(0); 39 | } 40 | 41 | .system-status { 42 | @include u-border-top(1px, 'primary-light'); 43 | @include u-padding-top(2); 44 | @include u-margin-top(1); 45 | display: flex; 46 | align-items: center; 47 | 48 | &::before { 49 | content: ''; 50 | width: 1.75rem; 51 | height: 1.75rem; 52 | display: inline-block; 53 | vertical-align: middle; 54 | margin-right: 0.25rem; 55 | background: url(../img/icon-system-status.svg) left center no-repeat; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /assets/scss/_not_found.scss: -------------------------------------------------------------------------------- 1 | html.not-found { 2 | height: 100%; 3 | } 4 | 5 | body.not-found { 6 | color: #fff; 7 | text-align: center; 8 | height: 100%; 9 | 10 | main { 11 | background-color: #112e51; 12 | } 13 | 14 | a, 15 | a:focus, 16 | a:hover { 17 | color: #fff; 18 | } 19 | 20 | .site-wrapper { 21 | height: 100%; 22 | min-height: 100%; 23 | width: 100%; 24 | display: table; 25 | } 26 | 27 | .site-wrapper-inner { 28 | display: table-cell; 29 | vertical-align: middle; 30 | } 31 | 32 | .cover-container { 33 | margin: auto; 34 | max-width: 600px; 35 | } 36 | 37 | .inner { 38 | padding: 0 30px; 39 | } 40 | 41 | .cover { 42 | padding: 0 20px; 43 | } 44 | 45 | .masthead-brand { 46 | margin-top: 10px; 47 | } 48 | 49 | ul { 50 | padding: 0; 51 | } 52 | 53 | li { 54 | display: inline; 55 | margin: 20px; 56 | } 57 | 58 | h1 { 59 | margin-top: 32px; 60 | margin-bottom: 24px; 61 | } 62 | 63 | @media (min-width: 768px) { 64 | .cover-container { 65 | width: 100%; 66 | } 67 | } 68 | 69 | @media (min-width: 992px) { 70 | .cover-container { 71 | width: 720px; 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /assets/scss/main.css.scss: -------------------------------------------------------------------------------- 1 | @use "uswds-core" as * with ( 2 | $theme-utility-breakpoints: ( 3 | "mobile": true, 4 | "tablet": true, 5 | "desktop": true 6 | ), 7 | $theme-grid-container-max-width: 'widescreen', 8 | $theme-footer-max-width: 'widescreen', 9 | $theme-header-max-width: 'widescreen', 10 | $theme-banner-max-width: 'widescreen', 11 | $theme-identifier-max-width: 'widescreen', 12 | $theme-in-page-nav-main-content-max-width: 'widescreen' 13 | 14 | ); 15 | @forward "uswds"; 16 | @forward "footer"; 17 | @forward "not_found"; 18 | 19 | $block-background-color: #fafafa; 20 | 21 | dd { 22 | margin-left: 0; 23 | } 24 | 25 | main.usa-layout-docs { 26 | word-wrap: break-word; 27 | } 28 | 29 | .dev-doc-row { 30 | border-top: 1px solid #CEDCED; 31 | padding-bottom: 2rem; 32 | 33 | h4 { 34 | margin-top: 1rem; 35 | } 36 | } 37 | 38 | .doc-sub-nav { 39 | width: 100%; 40 | margin-bottom: 0px; 41 | } 42 | 43 | .doc-sub-nav-item { 44 | display: inline-block; 45 | } 46 | 47 | .doc-sub-nav-item > a { 48 | color: #205493; 49 | text-decoration: none; 50 | cursor: pointer; 51 | } 52 | 53 | 54 | .usa-prose > ul > .doc-sub-nav-item { 55 | margin-bottom: 0px; 56 | } 57 | 58 | .code-button { 59 | color: #205493; 60 | padding-bottom: 0.5rem; 61 | border: none; 62 | text-align: left; 63 | padding-left: 0px; 64 | background-color: transparent; 65 | padding-right: 0px; 66 | } 67 | 68 | 69 | button.code-button:hover { 70 | cursor: pointer; 71 | } 72 | 73 | .code-button__selected { 74 | font-weight: bold; 75 | border-bottom: 4px solid red; 76 | } 77 | 78 | .reversefootnote { 79 | @include u-font-family("mono"); 80 | } 81 | 82 | .usa-layout-docs__sidenav { 83 | top: 2rem; 84 | } 85 | 86 | .code-snippet-section { 87 | position: sticky; 88 | top: 2rem; 89 | } 90 | 91 | .green-bottom-border { 92 | border-bottom: green 4px solid; 93 | } 94 | 95 | .red-bottom-border { 96 | border-bottom: red 4px solid; 97 | } 98 | 99 | .markdown > .highlighter-rouge > .highlight > pre { 100 | overflow-wrap: break-word; 101 | text-wrap: wrap; 102 | word-break: inherit; 103 | white-space-collapse: preserve-breaks; 104 | background-color: inherit; 105 | padding-bottom: 4rem; 106 | } 107 | 108 | .long.markdown > .highlighter-rouge > .highlight > pre { 109 | max-height: 480px; 110 | } 111 | 112 | .lookbook-embed-container { 113 | position: relative; 114 | overflow: hidden; 115 | width: 100%; 116 | height: 400px; 117 | } 118 | 119 | .lookbook-embed { 120 | position: absolute; 121 | top: 0; 122 | left: 0; 123 | bottom: 0; 124 | right: 0; 125 | width: 100%; 126 | height: 100%; 127 | } 128 | 129 | 130 | .return-to-top-section { 131 | position: absolute; 132 | height: 100%; 133 | bottom: 0; 134 | right: 0; 135 | } 136 | 137 | .return-to-top-button { 138 | max-width: 160px; 139 | // 5.6rem puts it nicely above the feedback survey button if 90% does not 140 | top: min(calc(100vh - 5.6rem), 90%); 141 | } 142 | 143 | .return-to-top-button > img { 144 | // Change the chevron to #0071bb from #000000 145 | filter: invert(21%) sepia(72%) saturate(4106%) hue-rotate(190deg) brightness(95%) contrast(101%); 146 | } 147 | 148 | .code-snippet-column { 149 | background-color: $block-background-color; 150 | position: relative; 151 | margin-top: 2rem; 152 | padding-top: 1rem; 153 | } 154 | 155 | .agency-logo-width{ 156 | width: 230px; 157 | } 158 | 159 | .usa-nav { 160 | float: none; 161 | } 162 | 163 | .usa-nav__close .usa-icon { 164 | width: 1.3rem; 165 | height: 1.3rem; 166 | } 167 | 168 | @media (min-width: 1024px) { 169 | .code-snippet-column { 170 | background-color: transparent; 171 | margin-top: 0px; 172 | padding-top: 0px; 173 | } 174 | 175 | .lookbook-embed-container { 176 | width: 700px; 177 | } 178 | 179 | .code-snippet-column::before { 180 | content: ""; 181 | right: -15px; 182 | width: 100%; 183 | display: block; 184 | z-index: -1; 185 | position: absolute; 186 | background-color: $block-background-color; 187 | top: 0; 188 | margin-top: -4rem; 189 | bottom: -15rem; 190 | } 191 | 192 | .markdown > .highlighter-rouge > .highlight > pre { 193 | overflow-wrap: break-word; 194 | text-wrap: wrap; 195 | word-break: inherit; 196 | white-space-collapse: preserve-breaks; 197 | } 198 | 199 | .hero { 200 | max-width: 60rem; 201 | margin-left: auto; 202 | margin-right: auto; 203 | } 204 | 205 | .usa-navbar.usa-navbar__full-width { 206 | max-width: 100%; 207 | } 208 | 209 | .usa-header--extended .usa-nav__inner.usa-nav__inner__no-margin { 210 | margin-left: 0px; 211 | max-width: 100%; 212 | } 213 | } 214 | -------------------------------------------------------------------------------- /assets/yaml/document_classification_error.yml: -------------------------------------------------------------------------------- 1 | failed_alerts: 2 | - name: Document Classification 3 | result: Attention -------------------------------------------------------------------------------- /assets/yaml/image_resolution_error.yml: -------------------------------------------------------------------------------- 1 | image_metrics: 2 | back: 3 | HorizontalResolution: 100 -------------------------------------------------------------------------------- /assets/yaml/individual_state_error.yml: -------------------------------------------------------------------------------- 1 | document: 2 | first_name: Susan 3 | last_name: Smith 4 | middle_name: Q 5 | address1: 1 Microsoft Way 6 | address2: Apt 3 7 | city: Bayside 8 | state: NY 9 | zipcode: '11364' 10 | dob: '1938-10-06' 11 | phone: +1 314-555-1212 12 | state_id_number: "mvatimeout" 13 | state_id_type: "drivers_license" 14 | state_id_jurisdiction: "WA" 15 | state_id_expiration: '2030-01-01' 16 | state_id_issued: '2020-01-01' 17 | issuing_country_code: 'US' 18 | -------------------------------------------------------------------------------- /assets/yaml/proofing.yml: -------------------------------------------------------------------------------- 1 | document: 2 | first_name: Susan 3 | last_name: Smith 4 | middle_name: Q 5 | address1: 1 Microsoft Way 6 | address2: Apt 3 7 | city: Bayside 8 | state: NY 9 | zipcode: '11364' 10 | dob: '1938-10-06' 11 | phone: +1 314-555-1212 12 | state_id_number: '123456789' 13 | state_id_type: drivers_license 14 | state_id_jurisdiction: 'NY' 15 | state_id_expiration: '2030-01-01' 16 | state_id_issued: '2020-01-01' 17 | issuing_country_code: 'US' 18 | -------------------------------------------------------------------------------- /assets/yaml/proofing_vendor_error.yml: -------------------------------------------------------------------------------- 1 | document: 2 | first_name: Parse 3 | last_name: Smith 4 | middle_name: Q 5 | address1: 1 Microsoft Way 6 | address2: Apt 3 7 | city: Bayside 8 | state: WA 9 | zipcode: '99237' 10 | dob: '1938-10-06' 11 | phone: +1 206-555-1212 12 | state_id_number: '123456789' 13 | state_id_type: drivers_license 14 | state_id_jurisdiction: 'WA' 15 | state_id_expiration: '2030-01-01' 16 | state_id_issued: '2020-01-01' 17 | issuing_country_code: 'US' 18 | -------------------------------------------------------------------------------- /assets/yaml/sample_full_error.yml: -------------------------------------------------------------------------------- 1 | doc_auth_result: Passed # values: Passed, Failed, Attention, Unknown 2 | image_metrics: 3 | back: 4 | HorizontalResolution: 300 # values: 0-600 5 | VerticalResolution: 450 # values: 0-600 6 | GlareMetric: 77 # values: 0-100 7 | SharpnessMetric: 88 # values: 0-100 8 | front: 9 | HorizontalResolution: 450 10 | VerticalResolution: 450 11 | GlareMetric: 100 12 | SharpnessMetric: 99 13 | failed_alerts: 14 | - name: 1D Control Number Valid # See list of valid names below 15 | result: Failed # values: Passed, Failed, Attention, Caution 16 | - name: 2D Barcode Content 17 | result: Attention 18 | passed_alerts: 19 | - name: Visible Pattern 20 | result: Passed 21 | portrait_match_results: 22 | FaceMatchResult: Pass # returns the portrait match result - values: Pass, Fail 23 | FaceErrorMessage: 'Successful. Liveness: Live' # returns the liveness result - values: 'Successful. Liveness: Live', 'Liveness: NotLive', 'Liveness: PoorQuality' 24 | -------------------------------------------------------------------------------- /favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GSA-TTS/identity-dev-docs/d4f66a8128ae2ab40dfa619bd34d74cd0a9d332a/favicon.ico -------------------------------------------------------------------------------- /federalist.json: -------------------------------------------------------------------------------- 1 | { 2 | "headers": [ 3 | { 4 | "/*.yml": { 5 | "Content-Disposition": "attachment" 6 | } 7 | } 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "identity-dev-docs", 3 | "version": "1.0.0", 4 | "type": "module", 5 | "scripts": { 6 | "prebuild:css": "mkdir -p _site/assets/css", 7 | "build:css": "build-sass assets/scss/*.scss --out-dir=_site/assets/css", 8 | "watch:css": "npm run build:css -- --watch", 9 | "pages": "npm run build:css", 10 | "lint": "eslint .", 11 | "test": "node --test spec/e2e/**" 12 | }, 13 | "repository": { 14 | "type": "git", 15 | "url": "git+https://github.com/GSA-TTS/identity-dev-docs.git" 16 | }, 17 | "license": "CC0-1.0", 18 | "bugs": { 19 | "url": "https://github.com/GSA-TTS/identity-dev-docs/issues" 20 | }, 21 | "homepage": "https://github.com/GSA-TTS/identity-dev-docs#readme", 22 | "dependencies": { 23 | "@18f/identity-build-sass": "^3.0.0", 24 | "@18f/identity-design-system": "^9.3.0" 25 | }, 26 | "devDependencies": { 27 | "@18f/eslint-plugin-identity": "^2.0.0", 28 | "@axe-core/puppeteer": "^4.10.0", 29 | "eslint": "^8.52.0", 30 | "eslint-plugin-import": "^2.29.0", 31 | "eslint-plugin-prettier": "^5.0.1", 32 | "fast-glob": "^3.3.2", 33 | "get-port": "^7.1.0", 34 | "prettier": "3.0.3", 35 | "puppeteer": "^22.15.0", 36 | "serve-handler": "^6.1.5" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /scripts/htmlproofer: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # Run HTMLProofer via Ruby so we can do advanced things like ignore bad peer certificates which turn 3 | # up in external links. 4 | require 'html-proofer' 5 | require 'optparse' 6 | require 'jekyll' 7 | 8 | proofer_options = { ignore_urls: [%r{\Ahttps://github.com/GSA-TTS/identity-dev-docs/edit}] } 9 | OptionParser.new do |opt| 10 | opt.on('--internal') { proofer_options[:disable_external] = true } 11 | opt.on('--external') { proofer_options[:external_only] = true } 12 | opt.on('--url-ignore PATTERN') { |pattern| proofer_options[:ignore_urls] << /#{Regexp.quote(pattern)}/ } 13 | opt.on('--allow-hash-href') { proofer_options[:allow_hash_href] = true } 14 | opt.on('--disallow-hash-href') { proofer_options[:allow_hash_href] = false } 15 | end.parse! 16 | 17 | site_config = Jekyll::Configuration.from(YAML.load_file('_config.yml')) 18 | 19 | proofer_options.merge!( 20 | allow_hash_href: true, 21 | empty_alt_ignore: true, 22 | typhoeus: { 23 | ssl_verifypeer: false, 24 | ssl_verifyhost: 0, 25 | followlocation: false, 26 | }, 27 | swap_urls: { 28 | "http://localhost:#{site_config['port']}" => 'https://developers.login.gov' 29 | } 30 | ) 31 | 32 | proofer = HTMLProofer.check_directory(site_config['destination'], proofer_options) 33 | proofer.before_request do |request| 34 | # Counter-intuitively, followlocation is set as false in the configuration and always reverted 35 | # to true before a request. External URL requests should be allowed to follow redirects, but 36 | # internal link trailing slash check is based on the raw options object. 37 | request.options[:followlocation] = true 38 | 39 | # Some URLs behave differently if `accept-language` header is not included. Remove this in the 40 | # future if it's no longer needed. 41 | request.options[:headers]['Accept-Language'] = '*' 42 | 43 | end 44 | 45 | proofer.run 46 | -------------------------------------------------------------------------------- /spec/e2e/accessibility.test.js: -------------------------------------------------------------------------------- 1 | import { describe, before, after, test, it } from 'node:test'; 2 | import assert from 'node:assert'; 3 | import { readFileSync } from 'node:fs'; 4 | import puppeteer from 'puppeteer'; 5 | import { AxePuppeteer } from '@axe-core/puppeteer'; 6 | import { createServer } from 'http'; 7 | import handler from 'serve-handler'; 8 | import getPort from 'get-port'; 9 | 10 | // only test canonical paths 11 | const paths = (() => { 12 | const file = readFileSync('./_site/sitemap.xml', { encoding: 'utf8' }); 13 | const pathMatch = file.matchAll(/(.+?\/)<\/loc>/g); 14 | return Array.from(pathMatch).map(([, url]) => new URL(url).pathname); 15 | })(); 16 | 17 | describe('accessibility', () => { 18 | /** @type {Server} */ 19 | let server; 20 | 21 | /** @type {number} */ 22 | let port; 23 | 24 | /** @type {import('puppeteer').Browser} */ 25 | let browser; 26 | 27 | before(async () => { 28 | port = await getPort(); 29 | browser = await puppeteer.launch({ 30 | args: ['--no-sandbox'], 31 | }); 32 | server = createServer((request, response) => 33 | handler(request, response, { public: '_site' }), 34 | ).listen(port); 35 | }); 36 | 37 | after(async () => { 38 | await Promise.all([browser.close(), server.close()]); 39 | }); 40 | 41 | it('has pages to test', () => { 42 | assert(paths.length); 43 | }); 44 | 45 | paths.forEach((path) => { 46 | test(path, async () => { 47 | const page = await browser.newPage(); 48 | await page.goto(`http://localhost:${port}${path}`); 49 | const results = await new AxePuppeteer(page) 50 | .withTags([ 51 | 'wcag2a', 52 | 'wcag2aa', 53 | 'wcag21a', 54 | 'wcag21aa', 55 | 'wcag22a', 56 | 'wcag22aa', 57 | 'best-practice', 58 | ]) 59 | .exclude('div[data-touchpoints-form-id]') 60 | // .exclude('a#fba-button[data-open-modal]') 61 | .analyze(); 62 | await page.close(); 63 | 64 | assert.deepStrictEqual(results.violations, []); 65 | }); 66 | }); 67 | }); 68 | -------------------------------------------------------------------------------- /spec/page.md_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | def redirect_page?(path) 4 | File.read(path).include?('