diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 000000000..ebab12145 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,62 @@ +{ + "root": true, + "ignorePatterns": [ + "projects/**/*", + "*.css" + ], + "overrides": [ + { + "files": [ + "*.ts" + ], + "parserOptions": { + "project": [ + "tsconfig.json" + ], + "createDefaultProgram": true + }, + "extends": [ + "plugin:@angular-eslint/recommended", + "plugin:@angular-eslint/template/process-inline-templates", + "plugin:prettier/recommended" + ], + "rules": { + "@angular-eslint/directive-selector": [ + "error", + { + "type": "attribute", + "prefix": "app", + "style": "camelCase" + } + ], + "@angular-eslint/component-selector": [ + "error", + { + "type": "element", + "prefix": "app", + "style": "kebab-case" + } + ] + } + }, + { + "files": [ + "*.html" + ], + "extends": [ + "plugin:@angular-eslint/template/recommended" + ], + "rules": {} + }, + { + "files": ["*.html"], + "excludedFiles": ["*inline-template-*.component.html"], + "extends": ["plugin:prettier/recommended"], + "rules": { + // NOTE: WE ARE OVERRIDING THE DEFAULT CONFIG TO ALWAYS SET THE PARSER TO ANGULAR (SEE BELOW) + "prettier/prettier": ["error", { "parser": "angular" }] + } + } + + ] +} diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 000000000..d19dbd61f --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,2 @@ +custom: https://owasp.org/donate/?reponame=www-project-devsecops-maturity-model&title=OWASP+Devsecops+Maturity+Model +github: OWASP diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..9060b7d91 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,15 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file + +version: 2 +updates: + - package-ecosystem: "npm" + directory: "/" + schedule: + interval: "weekly" + - package-ecosystem: "docker" + directory: "/" + schedule: + interval: "weekly" diff --git a/.github/proposal.md b/.github/proposal.md new file mode 100644 index 000000000..71cc0f281 --- /dev/null +++ b/.github/proposal.md @@ -0,0 +1,109 @@ +# OWASP DSOMM Enhancement Proposal + +## Overview + +This proposal outlines key enhancements to the OWASP DevSecOps Maturity Model (DSOMM) to improve its functionality, usability, and integration with other security frameworks. The total estimated effort for all proposed features is 268 hours (33.5 days). + +## Proposed Enhancements + +### 1. Vulnerability Management and Patch Management Expansion + +**Problem:** Current vulnerability management coverage is incomplete, particularly lacking metrics. +**Solution:** Integrate concepts from the Vulnerability Management Maturity Model and "Effective Vulnerability Management" book to add: +- New activities mapped to SAMM, ISO, and OpenCRE +- Risk and measure descriptions +- Implementation guidance +- Level justifications based on effort and security value + +**Estimated Effort:** 32 hours + +### 2. Compliance Date Integration + +**Problem:** Activity implementation status doesn't account for time-based assessment/compliance requirements. + +**Solution:** +As a security architect, I want teams to perform threat modeling quaterly. +As a project team, I perform a threat modeling and the status is DSOMM for that team is changed to "implemented". As there is no automatic removal of the status, it stays "implemented". + +Tasks: +- Add `threshold` attribute to activities for time-based assessment/compliance +- Enhance `teamsImplemented` attribute to track implementation dates +- Update UI to display assessment/compliance status based on dates and thresholds + +Sample `threshold`: +``` + threshold: + targets: + - type: "count" + minValue: 1 + period: + periodType: sliding + timeframe: "2Y" +``` +The `teamsImplemented` attribute, to be filled out by teams: +``` + teamsImplemented: + - teamA: + conductionDate: 2024-08-08 00:00:00 + - teamB: + conductionDate: 2024-08-08 00:00:00 + - teamB: + implemented: true +``` + +**Estimated Effort:** 80 hours + +### 3. Score Calculation + +**Problem:** Current visualization can be difficult to interpret quickly. + +**Solution:** Implement an overall score calculation for each sub-dimension, showing implemented vs. maximum possible activities for teams. + +**Estimated Effort:** 8 hours + +### 4. Customization Capabilities + +**Problem:** Organizations need to adapt DSOMM for their specific security programs, which is currently challenging. + +**Solution:** Make the DSOMM application customizable: +- Auto-adjust levels in visualizations when changed +- Allow hiding/adding attributes for activity descriptions +- Ensure consistent updates across linked elements (e.g., overview tables, detailed descriptions) + +**Estimated Effort:** 80 hours + +### 5. OpenCRE Integration Enhancement + +**Problem:** Current OpenCRE chatbot lacks comprehensive DSOMM content integration. + +**Solution:** +- Customize OpenCRE content with DSOMM-specific information +- Provide sample pre-questions for improved DSOMM coverage +- Create a guide for enhancing OpenCRE content for other projects + +The solution needs to be implemented together with openCRE team. + +**Estimated Effort:** 60 hours + +### 6. Status `notApplicable` +**Problem:** An application security program defines activities to be implemented by product teams. Sometimes, the activities are not applicable to a product/application. + +**Solution:** Add the status `notApplicable` for teams + +**Estimated Effort:** 8 hours + +## Total Estimated Effort + +268 hours (33.5 days) + +## Benefits + +- Improved vulnerability management guidance +- Better compliance tracking and reporting +- Enhanced data visualization and interpretation +- Increased flexibility for organizational adoption +- Tighter integration with broader security ecosystems + +## Conclusion + +These enhancements will significantly improve the usability, adaptability, and value of OWASP DSOMM for organizations implementing DevSecOps practices. The proposed changes will make DSOMM a more comprehensive and user-friendly tool for assessing and improving security maturity. diff --git a/.github/workflows/ESLint.yml b/.github/workflows/ESLint.yml new file mode 100644 index 000000000..bd98cae2f --- /dev/null +++ b/.github/workflows/ESLint.yml @@ -0,0 +1,11 @@ +name: ESLint Check +on: [push,pull_request] +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Install modules + run: yarn + - name: Run ESLint + run: yarn run eslint . --ext .js,.jsx,.ts,.tsx diff --git a/.github/workflows/depoy.yml b/.github/workflows/depoy.yml new file mode 100644 index 000000000..145aa5504 --- /dev/null +++ b/.github/workflows/depoy.yml @@ -0,0 +1,31 @@ +name: Deploy Heroku + +on: + workflow_dispatch: + + + +jobs: + heroku: + runs-on: ubuntu-latest + steps: + - name: "Check out Git repository" + uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac #v4.0.0 + - name: "Set Heroku app & branch for ${{ github.ref }}" + run: | + echo $GITHUB_REF + if [ "$GITHUB_REF" == "refs/heads/main" ]; then + echo "HEROKU_APP=" >> $GITHUB_ENV + fi + echo "HEROKU_BRANCH=main" >> $GITHUB_ENV + - name: Install Heroku CLI + run: | + curl https://cli-assets.heroku.com/install.sh | sh + - name: "Deploy ${{ github.ref }} to Heroku" + uses: akhileshns/heroku-deploy@v3.13.15 + with: + heroku_api_key: ${{ secrets.HEROKU_API_KEY }} + heroku_app_name: "dsomm" + heroku_email: timo.pagel@owasp.org + branch: ${{ env.HEROKU_BRANCH }} + usedocker: true diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml deleted file mode 100644 index 57ea8a8f1..000000000 --- a/.github/workflows/lint.yml +++ /dev/null @@ -1,17 +0,0 @@ -name: Lint -on: [push, pull_request] -jobs: - shellcheck: - name: runner / shellcheck - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f - - name: shellcheck - uses: reviewdog/action-shellcheck@bb5be3440d752c70c5ade03b2b6bf859316db5e2 - with: - github_token: ${{ secrets.github_token }} - reporter: github-pr-review - path: "." - pattern: "*.*sh" - exclude: "./.git/*" - shellcheck_flags: "--external-sources --exclude=SC1090,SC1091,SC2116,SC2015" diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index ba41dca52..248395aa1 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -2,31 +2,98 @@ name: CI on: push: - branches: [master] - pull_request: - branches: [master] + branches: [main] workflow_dispatch: schedule: - cron: "0 7 * * *" +permissions: + contents: write + issues: read + #pull-requests: write # to be able to comment on released pull requests + jobs: build: + if: github.repository == 'devsecopsmaturitymodel/DevSecOps-MaturityModel' runs-on: ubuntu-latest steps: - - uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f + - uses: actions/checkout@v3 + with: + persist-credentials: false # This is important if you have branch protection rules! + - name: Semantic Release + uses: cycjimmy/semantic-release-action@v4 + with: + branch: 'main' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Get Semantic Release Version + id: get-version + run: echo "::set-output name=version::$(grep -oP '\[\d+\.\d+\.\d+\]' CHANGELOG.md | tr -d '[]')" + + - name: show version + run: | + echo "Semantic Release Version: ${{ steps.get-version.outputs.version }}" + + - name: setup qemu for multi-arch build + uses: docker/setup-qemu-action@v2 + with: + platforms: amd64,arm64 + - name: setup buildx + uses: docker/setup-buildx-action@v2 - name: Log in to Docker Hub - uses: docker/login-action@v1 + uses: docker/login-action@v2 with: - registry: registry.hub.docker.com - username: ${{ secrets.HUB_USERNAME }} + #registry: registry.hub.docker.com + username: wurstbrot password: ${{ secrets.HUB_TOKEN }} - - name: create and push an image + - name: create and push dsomm image + uses: docker/build-push-action@v3 + with: + push: true + platforms: linux/amd64,linux/arm64 + tags: wurstbrot/dsomm:${{ steps.get-version.outputs.version }},wurstbrot/dsomm:latest + build-args: | + COMMIT_HASH=${{ github.sha }} + COMMIT_DATE=${{ github.event.head_commit.timestamp }} + GIT_BRANCH=${{ github.ref_name }} + # Commit all changed files back to the repository + - uses: planetscale/ghcommit-action@v0.1.6 + with: + commit_message: "🤖 fmt" + repo: ${{ github.repository }} + branch: ${{ github.head_ref || github.ref_name }} + env: + GITHUB_TOKEN: ${{secrets.ACCESS_TOKEN}} + heroku: + if: github.repository == 'devsecopsmaturitymodel/DevSecOps-MaturityModel' && github.event_name == 'push' && github.ref == 'refs/heads/main' + runs-on: ubuntu-latest + steps: + - name: "Check out Git repository" + uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac #v4.0.0 + - name: "Set Heroku app & branch for ${{ github.ref }}" run: | - chmod +x ./build.sh - if [ "${GITHUB_REF##*/}" == "master" ]; then - VERSION="2.5.${GITHUB_RUN_NUMBER}" - else - BRANCH_TO_DOCKER=$(echo ${GITHUB_REF##*/} | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9._-]//g') - VERSION="${BRANCH_TO_DOCKER}-${GITHUB_RUN_NUMBER}" + echo $GITHUB_REF + if [ "$GITHUB_REF" == "refs/heads/main" ]; then + echo "HEROKU_APP=" >> $GITHUB_ENV + echo "HEROKU_BRANCH=main" >> $GITHUB_ENV fi - sudo ./build.sh "registry.hub.docker.com" "wurstbrot" "dsomm" "${VERSION}" "${{ secrets.HUB_USERNAME }}" "${{ secrets.HUB_TOKEN }}" + echo "HEROKU_BRANCH=main" >> $GITHUB_ENV + - name: Install Heroku CLI + run: | + curl https://cli-assets.heroku.com/install.sh | sh + - name: "Deploy ${{ github.ref }} to Heroku" + uses: akhileshns/heroku-deploy@v3.13.15 + with: + heroku_api_key: ${{ secrets.HEROKU_API_KEY }} + heroku_app_name: "dsomm" + heroku_email: timo.pagel@owasp.org + branch: ${{ env.HEROKU_BRANCH }} + usedocker: true + docker_build_args: | + COMMIT_HASH + COMMIT_DATE + GIT_BRANCH + env: + COMMIT_HASH: ${{ github.sha }} + COMMIT_DATE: ${{ github.event.head_commit.timestamp }} + GIT_BRANCH: ${{ github.ref_name }} diff --git a/.github/workflows/stale.yaml b/.github/workflows/stale.yaml new file mode 100644 index 000000000..039917b92 --- /dev/null +++ b/.github/workflows/stale.yaml @@ -0,0 +1,24 @@ +name: 'Close stale issues and PR' +on: + schedule: + - cron: '30 1 * * *' + +jobs: + stale: + runs-on: ubuntu-latest + steps: + - uses: actions/stale@v9 + with: + stale-issue-message: > + This issue has been automatically marked as `stale` because it has not had + recent activity. :calendar: It will be _closed automatically_ in one week if no further activity occurs. + stale-pr-message: > + This PR has been automatically marked as `stale` because it has not had + recent activity. :calendar: It will be _closed automatically_ in two weeks if no further activity occurs. + close-issue-message: This issue was closed because it has been stalled for 7 days with no activity. + close-pr-message: This PR was closed because it has been stalled for 20 days with no activity. + days-before-stale: 35 + days-before-close: 7 + days-before-pr-close: 20 + exempt-issue-labels: 'critical,technical debt' + exempt-assignees: wurstbrot diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml deleted file mode 100644 index 196963cd2..000000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,14 +0,0 @@ -name: Test -on: [push, pull_request] -jobs: - test: - name: Test Code - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1.0.0 - - name: test code - run: | - chmod +x ./tests.sh - sudo apt install -y php - ./tests.sh - diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 000000000..9d09dd6f9 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,18 @@ +name: Unit Tests + +on: [push, pull_request] + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v1 + - name: Use Node.js 16.16.0 + uses: actions/setup-node@v1 + with: + node-version: 16.0 + - name: Install dependencies + run: npm install --legacy-peer-deps + - name: Test + run: npm test -- --watch=false --browsers=ChromeHeadless diff --git a/.gitignore b/.gitignore index 99ec2918d..70387d7c6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,47 @@ -.idea -data/generated -*~ -/vendor +# See http://help.github.com/ignore-files/ for more about ignoring files. + +# angular cache +/.angular/cache + +# compiled output +/dist +/tmp +/out-tsc + +# dependencies +/node_modules + +# IDEs and editors +/.idea +.project +.classpath +.c9/ +*.launch +.settings/ +*.sublime-workspace + +# IDE - VSCode +.vscode/* +!.vscode/settings.json + +# Cache +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json + +# misc +/.sass-cache +/connect.lock +/coverage +/libpeerconnection.log +npm-debug.log +yarn-error.log +testem.log +/typings + +# System Files +.DS_Store +Thumbs.db +/yaml-generation/vendor/ +# Generated YAML +/src/assets/YAML/generated/generated.yaml diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 000000000..353e4b75e --- /dev/null +++ b/.prettierignore @@ -0,0 +1,46 @@ +# See http://help.github.com/ignore-files/ for more about ignoring files. + +# angular cache +/.angular/cache + +# compiled output +/dist +/tmp +/out-tsc + +# dependencies +/node_modules + +# IDEs and editors +/.idea +.project +.classpath +.c9/ +*.launch +.settings/ +*.sublime-workspace + +# IDE - VSCode +.vscode/* +!.vscode/settings.json + +# Cache +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json + +# misc +/.sass-cache +/connect.lock +/coverage +/libpeerconnection.log +npm-debug.log +yarn-error.log +testem.log +/typings + +# System Files +.DS_Store +Thumbs.db + +/src/assets/YAML/generated/generated.yaml \ No newline at end of file diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 000000000..e0daba441 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,12 @@ +{ + "tabWidth": 2, + "useTabs": false, + "singleQuote": true, + "semi": true, + "bracketSpacing": true, + "arrowParens": "avoid", + "trailingComma": "es5", + "bracketSameLine": true, + "printWidth": 100, + "endOfLine": "auto" + } \ No newline at end of file diff --git a/.releaserc.json b/.releaserc.json new file mode 100644 index 000000000..5a5728224 --- /dev/null +++ b/.releaserc.json @@ -0,0 +1,17 @@ +{ + "branch": "main", + "plugins": [ + [ + "@semantic-release/commit-analyzer", + { + "preset": "angular", + "releaseRules": [ + {"breaking": true, "release": "minor"}, + {"tag": "Breaking", "release": "minor"} + ] + } + ], + "@semantic-release/release-notes-generator", + "@semantic-release/github" + ] +} diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 000000000..1a9c7a7cc --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,42 @@ +# [3.10.0](https://github.com/devsecopsmaturitymodel/DevSecOps-MaturityModel/compare/v3.9.0...v3.10.0) (2023-11-10) + + +### Features + +* decouple yaml-data and application ([45611e8](https://github.com/devsecopsmaturitymodel/DevSecOps-MaturityModel/commit/45611e8ee58ec7e9ed8ecf5bb1c54b5bfcb8e885)) +* enhance signing description ([231a5e9](https://github.com/devsecopsmaturitymodel/DevSecOps-MaturityModel/commit/231a5e97b66a49b95bbc14147ea43d5ce9646788)) + +# [3.9.0](https://github.com/devsecopsmaturitymodel/DevSecOps-MaturityModel/compare/v3.8.0...v3.9.0) (2023-11-09) + + +### Features + +* enhance signing description ([4546078](https://github.com/devsecopsmaturitymodel/DevSecOps-MaturityModel/commit/454607882a909ef5d7c3e5f2f14bcc0a6a43076e)) + +## [3.5.2](https://github.com/devsecopsmaturitymodel/DevSecOps-MaturityModel/compare/v3.5.1...v3.5.2) (2023-11-07) + + +### Bug Fixes + +* YAML Structure description ([33e50f0](https://github.com/devsecopsmaturitymodel/DevSecOps-MaturityModel/commit/33e50f0fb168c5c91b4fedb5a2a7d5e8a4ac0a80)) + +## [3.5.1](https://github.com/devsecopsmaturitymodel/DevSecOps-MaturityModel/compare/v3.5.0...v3.5.1) (2023-11-07) + + +### Bug Fixes + +* YAML ([889422b](https://github.com/devsecopsmaturitymodel/DevSecOps-MaturityModel/commit/889422b791cf141838e2ec637406a14d8849ff6a)) + +# [3.5.0](https://github.com/devsecopsmaturitymodel/DevSecOps-MaturityModel/compare/v3.4.0...v3.5.0) (2023-11-07) + + +### Features + +* add WAF ([a98947d](https://github.com/devsecopsmaturitymodel/DevSecOps-MaturityModel/commit/a98947da41691e23af255cad8778208db09ccc53)) + +# [3.4.0](https://github.com/devsecopsmaturitymodel/DevSecOps-MaturityModel/compare/v3.3.0...v3.4.0) (2023-11-07) + + +### Features + +* Activity Contexualized Encoding ([f81d3cf](https://github.com/devsecopsmaturitymodel/DevSecOps-MaturityModel/commit/f81d3cfedd013b579fac73e1b62bb57dfbc5a7a3)) diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 000000000..cf224c0f1 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,111 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for +everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity +and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, caste, +color, religion, or sexual identity and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience +* Focusing on what is best not just for us as individuals, but for the overall community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or advances of any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email address, without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take +appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, +issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for +moderation decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing +the community in public spaces. Examples of representing our community include using an official e-mail address, posting +via an official social media account, or acting as an appointed representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible +for enforcement at +[bjoern.kimminich@owasp.org](mailto:bjoern.kimminich@owasp.org). All complaints will be reviewed and investigated +promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem +in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the +community. + +**Consequence**: A private, written warning from community leaders, providing clarity around the nature of the violation +and an explanation of why the behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series of actions. + +**Consequence**: A warning with consequences for continued behavior. No interaction with the people involved, including +unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding +interactions in community spaces as well as external channels like social media. Violating these terms may lead to a +temporary or permanent ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified +period of time. No public or private interaction with the people involved, including unsolicited interaction with those +enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate +behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within the community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.0, available at +[https://www.contributor-covenant.org/version/2/0/code_of_conduct.html][v2.0]. + +Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder][Mozilla CoC]. + +For answers to common questions about this code of conduct, see the FAQ +at [https://www.contributor-covenant.org/faq][FAQ]. Translations are available at +[https://www.contributor-covenant.org/translations][translations]. + +[homepage]: https://www.contributor-covenant.org + +[v2.0]: https://www.contributor-covenant.org/version/2/0/code_of_conduct.html + +[Mozilla CoC]: https://github.com/mozilla/diversity + +[FAQ]: https://www.contributor-covenant.org/faq + +[translations]: https://www.contributor-covenant.org/translations diff --git a/Caddyfile b/Caddyfile new file mode 100644 index 000000000..f28b4dda3 --- /dev/null +++ b/Caddyfile @@ -0,0 +1,20 @@ +{ + http_port {$PORT} +} + +:{$PORT}, localhost:{$PORT} { + log stdout + file_server { + root /srv + } + try_files {path} {path}/ /index.html + + header / { + X-Content-Type-Options "nosniff" + X-XSS-Protection "1; mode=block" + X-Robots-Tag "none" + X-Download-Options "noopen" + X-Permitted-Cross-Domain-Policies "none" + Referrer-Policy "no-referrer" + } +} diff --git a/Development.md b/Development.md new file mode 100644 index 000000000..232bdf22c --- /dev/null +++ b/Development.md @@ -0,0 +1,72 @@ +# DevSecOps Maturity Model (DSOMM) + +## Introduction + +The DevSecOps Maturity Model (DSOMM) is an open-source framework designed to help organizations evaluate and improve their **DevSecOps** practices. +It provides structured **security maturity levels**, recommendations, and automation insights to enable teams to build **secure, efficient, and scalable software**. + +This guide walks you through **setting up the project locally**, making contributions, and submitting a pull request. + +## **Project Setup** + +### Development Server + +The DSOMM is based [Angular](https://angular.dev/) and uses npm for package management. + +- If you have not yet installed npm or the Angular command line tools, install them now. First [NodeJS](https://nodejs.org/en/download) (which provides npm), then Angular: + +```bash +npm install -g @angular/cli +``` + +- Clone the DSOMM repo + +```bash +git clone https://github.com/devsecopsmaturitymodel/DevSecOps-MaturityModel.git +``` + +- Change directory to DSOMM + +```bash +cd DevSecOps-MaturityModel +``` + +- Install Dependencies + +```bash +npm install +``` + +- **NB!** The DSOMM activities are maintained separately. Download the `generated.yaml` and put it in the required folder + +```bash +curl https://raw.githubusercontent.com/devsecopsmaturitymodel/DevSecOps-MaturityModel-data/main/src/assets/YAML/generated/generated.yaml -o src/assets/YAML/generated/generated.yaml +``` + +- Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The application will automatically reload if you change any of the source files. + +## Code Scaffolding + +Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`. + +## Build + +Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. + +## Running Unit Tests + +Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). + +## Coding Style Conventions + +- We follow the coding style defined by [ESLint](https://eslint.org/). +- We also use [Prettier](https://prettier.io/docs/en/index.html) as our opinionated code formatter. +- To validate the schemas of the DSOMM yaml files in the IDE, it is recommended to use the VS Code extension [redhat.vscode-yaml](https://marketplace.visualstudio.com/items?itemName=redhat.vscode-yaml). The schemas are stored in `/src/assets/YAML/schemas` + +### Running Linter + +Run `ng lint` to run the linter from the command line. +If you want to lint only a specific component, use: + +```bash +ng lint --lint-file-patterns .\src\app\component\xxxxxx\ diff --git a/Dockerfile b/Dockerfile index 70e51046a..7415a2d16 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,18 +1,29 @@ -FROM composer AS vendor -COPY composer.json composer.json -COPY composer.lock composer.lock -RUN composer install \ - --ignore-platform-reqs \ - --no-interaction \ - --no-plugins \ - --no-scripts \ - --prefer-dist - -FROM php:apache-buster -RUN apt-get update && apt-get -y dist-upgrade && apt-get -y install apt-utils libyaml-dev wget -RUN pecl channel-update pecl.php.net && pecl install yaml && docker-php-ext-enable yaml -RUN echo "ServerName localhost" >> /etc/apache2/apache2.conf -COPY . /var/www/html/ -RUN chmod 777 /var/www/html/selectedData.csv -COPY --from=vendor /app/vendor/ /var/www/html/vendor/ -RUN ENFORCE_DATA_GENERATION_DURING_RUNTIME=true php data/generateDimensions.php && chmod -R 777 data/generated +FROM node:24.7.0-alpine3.22 AS build + +ARG COMMIT_HASH +ARG COMMIT_DATE +ARG GIT_BRANCH + +WORKDIR /usr/src/app +COPY package.json package-lock.json ./ + +RUN apk add --upgrade python3 build-base py3-setuptools py3-pip \ + && pip3 install --break-system-packages setuptools \ + && npm install +COPY . . +RUN npm run build --configuration=production + +RUN mkdir -p /usr/src/app/dist/dsomm/assets && \ + echo "commit: \"${COMMIT_HASH:-unknown}\"" > /usr/src/app/dist/dsomm/assets/build-info.yaml && \ + echo "commit_date: \"${COMMIT_DATE:-unknown}\"" >> /usr/src/app/dist/dsomm/assets/build-info.yaml && \ + echo "branch: \"${GIT_BRANCH:-unknown}\"" >> /usr/src/app/dist/dsomm/assets/build-info.yaml + + +FROM wurstbrot/dsomm-yaml-generation:1.24.0 AS yaml + +FROM caddy:2.10.2 +ENV PORT=8080 + +COPY Caddyfile /etc/caddy/Caddyfile +COPY --from=build ["/usr/src/app/dist/dsomm/", "/srv"] +COPY --from=yaml ["/var/www/html/generated/model.yaml", "/srv/assets/YAML/default/model.yaml"] diff --git a/INSTALL.md b/INSTALL.md new file mode 100644 index 000000000..6ac79ccc8 --- /dev/null +++ b/INSTALL.md @@ -0,0 +1,151 @@ +# Install DSOMM +The DSOMM application is frontend only. Data is only stored in server side YAML files, and in the localStorage im the user's browser. + +The application can be deployed in many ways. using a number of Docker, Amazon AWS and a standalone Angular service. + +## Get the Activities + +The _DSOMM activities_ are maintained in a separate GitHub repository. For the latest version, get it from: +- https://github.com/devsecopsmaturitymodel/DevSecOps-MaturityModel-data + + +## Docker +1. Install [Docker](https://www.docker.com) +1. Download and run DSOMM: \ + `docker pull wurstbrot/dsomm:latest` \ + `docker run --rm -p 8080:8080 wurstbrot/dsomm:latest` +1. Open DSOMM on http://localhost:8080 + - If you are using docker-machine instead of the native docker installation on Windows or macOs: open instead +If you want to override the default `generated.yaml` you can mount this file when starting the docker command. + +`docker run --rm --volume $PWD/generated.yaml:/srv/assets/YAML/generated/generated.yaml -p 8080:8080 wurstbrot/dsomm` + +**NB!** Note that the docker command requires an absolute path to the local file. (Hence, the use of the `$PWD` variable. On Windows, substitute `$PWD` with `%CD%`.) + + +## Amazon EC2 Instance + +1. In the _EC2_ sidenav select _Instances_ and click _Launch Instance_ +2. In _Step 1: Choose an Amazon Machine Image (AMI)_ choose an _Amazon + Linux AMI_ or _Amazon Linux 2 AMI_ +3. In _Step 3: Configure Instance Details_ unfold _Advanced Details_ and + copy the script below into _User Data_ +4. In _Step 6: Configure Security Group_ add a _Rule_ that opens port 80 + for HTTP +5. Launch your instance +6. Browse to your instance's public DNS + +```bash +#!/bin/bash +service docker start +docker run -d -p 80:8080 wurstbrot/dsomm:latest +``` + + +## Any web server - Angular build +Since DSOMM is a frontend only application, any web server can host DSOMM. +- Clone the DSOMM repo + +- **NB!** The DSOMM activities are maintained separately. Download the `generated.yaml` and put it in the required folder +``` +git clone https://github.com/devsecopsmaturitymodel/DevSecOps-MaturityModel.git +cd DevSecOps-MaturityModel +npm install +curl https://raw.githubusercontent.com/devsecopsmaturitymodel/DevSecOps-MaturityModel-data/main/src/assets/YAML/generated/generated.yaml -o src/assets/YAML/generated/generated.yaml +ng build +``` +The files that were created in the subfolder `dist` + +If your DSOMM application is having a subfolder in the URL (e.g. https://server.local/our-dsomm), you need to build the Angular application to prepare for this. In that case build the application by using `ng build --base-href /our-dsomm/`. + + +## Teams and Groups +To customize these teams, you can create your own [meta.yaml](src/assets/meta.yaml) file with your unique team definitions. + +Assessments within the framework can be based on either a team or a specific application, which can be referred to as the context. Depending on how you define the context or teams, you may want to group them together. + +Here are a couple of examples to illustrate this, in breakers the DSOMM word: +- Multiple applications (teams) can belong to a single overarching team (application). +- Multiple teams (teams) can belong to a larger department (group). + +Feel free to create your own [meta.yaml](src/assets/meta.yaml) file to tailor the framework to your specific needs and mount it in your environment (e.g. kubernetes or docker). +Here is an example to start docker with customized meta.yaml: +``` +# Customized meta.yaml +cp src/assets/YAML/meta.yaml . +docker run -v $(pwd)/meta.yaml:/srv/assets/YAML/meta.yaml -p 8080:8080 wurstbrot/dsomm + +# Customized meta.yaml and generated.yaml +cp src/assets/YAML/meta.yaml . +cp $(pwd)/src/assets/YAML/generated/generated.yaml . +docker run -v $(pwd)/meta.yaml:/srv/assets/YAML/meta.yaml -v $(pwd)/generated.yaml:/srv/assets/YAML/generated/generated.yaml -p 8080:8080 wurstbrot/dsomm +``` + +In the corresponding [dimension YAMLs](https://github.com/devsecopsmaturitymodel/DevSecOps-MaturityModel-data/tree/main/src/assets/YAML/default), use: +``` +[...] + teamsImplemented: + Default: false + B: true + C: true + teamsEvidence: + B: All team members completed OWASP Secure Coding Dojo training on 2025-01-11. + C: | + The pentest report from 2025 has been split into Jira tasks under + [TODO-123](https://jira.example.com/issues/TODO-123). + + _2025-04-01:_ All fixes of **critical** findings are deployed to production. +``` +The `|` is yaml syntax to indicate that the evidence spans multiple lines. Markdown +syntax can be used. The evidence is currently visible on the activity from the Matrix page. + +# Back link + +- [OWASP DevSecOps maturity model page](https://dsomm.owasp.org/) +- [OWASP DevSecOps project page](https://owasp.org/www-project-devsecops-maturity-model/) +- [OWASP](https://owasp.org) + +# Your help is needed to perform + +* Adding a manual on how to use DSOMM +* Integration of Incident Response +* DevSecOps Toolchain Categorization +* App Sec Maturity Models Mapping +* CAMS Categorization +* Adding assessment questions + +# Multi-language support +Multi-language support is not currently planned. + +# Sponsors + +[![Timo Pagel IT-Consulting](https://raw.githubusercontent.com/DefectDojo/Documentation/master/doc/img/timo-pagel-logo.png)](https://pagel.pro) + +[![Apprio Inc](https://github.com/wurstbrot/DevSecOps-MaturityModel/raw/master-old/assets/images/Apiiro_black_logo.png)](https://apiiro.com/) + +[![Heroku (hosting)](https://github.com/wurstbrot/DevSecOps-MaturityModel/raw/main/src/assets/images/sponsors/heroku.png)](https://www.heroku.com/open-source-credit-program) + +# Donations + +If you are using the model or you are inspired by it, want to help but don't want to create pull requests? You can donate at the [OWASP Project Wiki Page](https://owasp.org/donate/?reponame=www-project-devsecops-maturity-model&title=OWASP+Devsecops+Maturity+Model). Donations might be used for the design of logos/images/design or travels. + +# License + +This program is free software: you can redistribute it and/or modify it under the terms of the [GPL 3](https://www.gnu.org/licenses/) license. + +The intellectual property (content in the _data_ folder) is licensed under Attribution-ShareAlike. +An example attribution by changing the content: +> This work is based on the [OWASP DevSecOps Maturity Model](https://dsomm.owasp.org/). + +The OWASP DevSecOps Maturity Model and any contributions are Copyright © by Timo Pagel 2017-2025. + + +For customized DSOMM, take a look at https://github.com/wurstbrot/DevSecOps-MaturityModel-custom. + +You can download your current state from the circular heatmap and mount it again via + +```bash +wget https://raw.githubusercontent.com/devsecopsmaturitymodel/DevSecOps-MaturityModel-data/main/src/assets/YAML/generated/generated.yaml # or go to /circular-heatmap and download edited yaml (bottom right) +docker run -p 8080:8080 -v /tmp/generated.yaml:/srv/assets/YAML/generated/generated.yaml wurstbrot/dsomm:latest +``` + diff --git a/Issue.md b/Issue.md new file mode 100644 index 000000000..a4e6e0588 --- /dev/null +++ b/Issue.md @@ -0,0 +1,59 @@ +# Changing team names has no effect + +## Expected outcome +* Updating the teams names and groups in `meta.yaml` should be visible in the browser after a refresh + +## Actual outcome + +## Steps to reproduce +1) Clone the repo \ + `git clone https://github.com/devsecopsmaturitymodel/DevSecOps-MaturityModel.git` + +2) Install dependencies \ + `cd DevSecOps-MaturityModel` \ + `npm install` + +3) Download the default teams setup \ + `curl https://raw.githubusercontent.com/devsecopsmaturitymodel/DevSecOps-MaturityModel-data/main/src/assets/YAML/generated/generated.yaml -o src/assets/YAML/generated/generated.yaml` + +4) Start the web server \ + `ng server` (or maybe `npx ng server`) + +5) Open *incognito mode* os a web browser and visit \ + http://localhost:4200/circular-heatmap + +6) Verify that the teams are 'Default', 'B' and 'C' + +7) Fill in data for some of the teams + - Click on a sector in the circle (e.g. *Build* Level 1) + - Expand *Defined build process* + - Tick all three teams + - Click on another sector in the circle (e.g. *Deployment* Level 1) + - Expand *Defined deployment process* + - Tick 'Default' and 'B' only + +8) Download `generated.yaml` + +### Change names of teams +9) Open `src\assets\YAML\meta.yaml` +10) Edit team names in 'meta' + - Rename `Default` to `A` in `teams` and `teamGroups` + - Add `D` on `teams` and `teamGroups.GroupA` + - Add `GroupD: ['C', 'D']` under `teamGroups` +11) Update team names in 'generated' + - Rename all `Default:` to `A:` in the downloaded `generated.yaml` + - Add `D: true` on line 130 for *Defined build process* + +12) Replace `src/assets/YAML/generated/generated.yaml` with the newly modified version + +### Verify data in your browser +13) Refresh your browser + * The team filters are showing the new names + * But expanding the activity cards only show `B` and `C` + + + + + + + diff --git a/README.md b/README.md index 12384cea5..04ea87540 100644 --- a/README.md +++ b/README.md @@ -4,28 +4,32 @@ From a startup to a multinational corporation the software development industry The OWASP DevSecOps Maturity Model provides opportunities to harden DevOps strategies and shows how these can be prioritized. -With the help of DevOps strategies security can also be enhanced. For example, each component such as application libraries and operating system libraries in docker images can be tested for known vulnerabilities. +With the help of DevOps strategies security can also be enhanced. For example, each component such as application libraries and operating system libraries in docker images can be tested for known vulnerabilities. Attackers are intelligent and creative, equipped with new technologies and purpose. Under the guidance of the forward-looking DevSecOps Maturity Model, appropriate principles and measures are at hand implemented which counteract the attacks. # Usage -Go to https://dsomm.timo-pagel.de or clone [this repository](https://github.com/wurstbrot/DevSecOps-MaturityModel/) and run `startDocker.bash`. +Go to https://dsomm.owasp.org. * _matrix_ shows the dimensions, subdimensions and activities are described. -* _Implementation Levels_ can be used to measure the current implementation level by clicking on the specific activities which have been performed. -* _Ease and Value of Implementation_ is used for the maturity model development to see the ease and value of each activity to be able to compare it with activities within the subdimension and activities from other subdimensions. -* _Dependenies_ shows the dependencies between activities -* _Useage_ describes the dimensions -* _Full Report_ prints all activities to be able to print it +* _Implementation Levels_ can be used to show the current implementation level by clicking on the specific activities which have been performed (it is recommended to use a gitops-like flow) +* _Mappings_ Shows mappings to other standards and provides the ability to download an excel sheet +* _Usage_ describes how to use DSOMM In this [video](https://www.youtube.com/watch?v=tX9RHZ_O5NU) Timo Pagel describes different strategic approaches for your secure DevOps strategy. The use OWASP DSOMM in combination with [OWASP SAMM](https//owaspsamm.org) is explained. In case you have evidence or review questions to gather evidence, you can add the attribute "evidence" to an activity which will be attached to an activity to provide it to your CISO or your customer's CISO. You can switch on to show open TODO's for evidence by changing IS_SHOW_EVIDENCE_TODO to true 'bib.php' `define(IS_SHOW_EVIDENCE_TODO, true);` -# Community +This page uses the Browser's localStorage to store the state of the circular headmap. + +# Changes +Changes to the application are displayed at the release page of [DevSecOps-MaturityModel](https://github.com/devsecopsmaturitymodel/DevSecOps-MaturityModel-data/releases). +Changes to the maturity model content are displayed at the release page of [DevSecOps-MaturityModel-data](https://github.com/devsecopsmaturitymodel/DevSecOps-MaturityModel-data/releases). + +# Community Join #dsomm in [OWASP Slack](https://owasp.slack.com/join/shared_invite/zt-g398htpy-AZ40HOM1WUOZguJKbblqkw#/). Create issues or even better Pull Requests in [github](https://github.com/wurstbrot/DevSecOps-MaturityModel/). @@ -33,7 +37,6 @@ Create issues or even better Pull Requests in [github](https://github.com/wurstb * [Video: OWASP (DevSecOps) Projects, 2021-04-28, OWASP Stammtisch Frankfurt](https://www.youtube.com/watch?v=8webiYnF56A) * [Video: DSOMM Enhancement Workshop at Open Security Summit, 2021-04-16](https://youtu.be/H2BA6gaeKBE) * [Video: Strategic Usage of the OWASP Software Assurance Maturity Model and the OWASP DevSecOps Maturity Model, OWASP Jakarta](https://m.youtube.com/watch?v=lLMLGIzl56M) -* [Slides: DSOMM Overview](https://docs.google.com/presentation/d/1eQcE_AsR1g6uOVf3B2Ehh1g0cHvPknkdLY4BzMYatSw/edit?usp=sharing) * [Video: GitHub practical DSOMM snippet on twitch](https://www.twitch.tv/githubenterprise/clip/EsteemedTriumphantMinkFailFish) * [Blog: GitHub on DSOMM](https://github.blog/2020-08-06-achieving-devsecops-maturity-with-a-developer-first-community-driven-approach/) 2020 * [Video: Benutzung vom OWASP DevSecOps Maturity Model (German)](https://vimeo.com/456523229) @@ -55,31 +58,22 @@ In case you would like to perform a DevSecOps assessment, the following tools ar ## Container 1. Install [Docker](https://www.docker.com) -2. Run `docker run --rm -p 8080:80 wurstbrot/dsomm:latest +2. Run `docker pull wurstbrot/dsomm:latest && docker run --rm -p 8080:8080 wurstbrot/dsomm:latest` 3. Browse to (on macOS and Windows browse to if you are using docker-machine instead of the native docker installation) -In case you would like to have perform an assessment for multiple teams, iterate from port 8080 to 8XXX, depending of the size of your team. -In case the application should be visible, but the "Implementation Level" shouldn't be changeable, consider the following code: - -```bash -#!/bin/bash -set -xe - -IMAGE_NAME="/dsomm:latest" +For customized DSOMM, take a look at https://github.com/wurstbrot/DevSecOps-MaturityModel-custom. -rm -Rf DevSecOps-MaturityModel || true -git clone git@github.com:wurstbrot/DevSecOps-MaturityModel.git -cp data/* DevSecOps-MaturityModel/data -cp -a selectedData.csv DevSecOps-MaturityModel/selectedData.csv +You can download your current state from the circular heatmap and mount it again via -cd DevSecOps-MaturityModel -docker build -t $IMAGE_NAME . -docker push $IMAGE_NAME +```bash +wget https://raw.githubusercontent.com/devsecopsmaturitymodel/DevSecOps-MaturityModel-data/main/src/assets/YAML/generated/generated.yaml # or go to /circular-heatmap and download edited yaml (bottom right) +docker run -p 8080:8080 -v /tmp/generated.yaml:/srv/assets/YAML/generated/generated.yaml wurstbrot/dsomm:latest ``` -This approach also allows teams to perform self assessment with changes tracked in a repository. +. +This approach also allows teams to perform self assessment with changes tracked in a repository. ## Amazon EC2 Instance @@ -95,33 +89,79 @@ This approach also allows teams to perform self assessment with changes tracked ```bash #!/bin/bash -yum update -y -yum install -y docker service docker start -docker run -d -p 80:80 wurstbrot/dsomm:latest +docker run -d -p 80:8080 wurstbrot/dsomm:latest ``` -## Tests +## Generating the `generated.yaml` File -To run basic tests just +The `generated.yaml` file is dynamically created during the build process. If you don’t see this file after setup, follow these steps to generate it: -```bash -docker-compose -f docker-compose.dev.yaml up test-php +**1. Clone the Required Repository:** +The `generated.yaml` file is built via the DevSecOps-MaturityModel-data repository. Make sure you have cloned and set it up correctly. + +**2. Run the Build Command:** +Navigate to the project directory and run the following command: +- *Using npm:* + +```sh +npm run build +```` + +- *Using yarn:* + +```sh +yarn build ``` -# Credits +*If the file is missing, ensure all dependencies are installed and that you have the correct access to the `DevSecOps-MaturityModel-data` repository.* + +## Activity Definitions +The definition of the activities are in the [data-repository](https://github.com/devsecopsmaturitymodel/DevSecOps-MaturityModel-data). + +## Teams and Groups +To customize these teams, you can create your own [meta.yaml](src/assets/YAML/meta.yaml) file with your unique team definitions. -* The dimension _Test and Verification_ is based on Christian Schneiders [Security DevOps Maturity Model (SDOMM)](https://www.christian-schneider.net/SecurityDevOpsMaturityModel.html). _Application tests_ and _Infrastructure tests_ are added by Timo Pagel. Also, the sub-dimension _Static depth_ has been evaluated by security experts at [OWASP Stammtisch Hamburg](https://www.owasp.org/index.php/OWASP_German_Chapter_Stammtisch_Initiative/Hamburg). -* The sub-dimension Process has been added after a discussion with [Francois Raynaud](https://www.linkedin.com/in/francoisraynaud/) that reactive activities are missing. -* Enhancement of my basic translation is performed by [Claud Camerino](https://github.com/clazba). -* Adding ISO 27001:2017 mapping, [Andre Baumeier](https://github.com/AndreBaumeier). -* Providing a documentation of how to use `docker` in the Juice Shop for simple copy&paste, [Björn Kimminich](https://github.com/bkimminich/). -* [OWASP Project Integration Project Writeup](https://github.com/OWASP/www-project-integration-standards/blob/master/writeups/owasp_in_sdlc/index.md) for providing documentation on different DevSecOps practices which are copied&pasted/ (and adopted) (https://github.com/northdpole, https://github.com/ThunderSon) -* The requirements from [level 0](https://github.com/AppSecure-nrw/security-belts/blob/master/white/) are based on/copied from [AppSecure NRW](https://appsecure.nrw/) +Assessments within the framework can be based on either a team or a specific application, which can be referred to as the context. Depending on how you define the context or teams, you may want to group them together. + +Here are a couple of examples to illustrate this, in breakers the DSOMM word: +- Multiple applications (teams) can belong to a single overarching team (application). +- Multiple teams (teams) can belong to a larger department (group). + +Feel free to create your own [meta.yaml](src/assets/YAML/meta.yaml) file to tailor the framework to your specific needs and mount it in your environment (e.g. kubernetes or docker). +Here is an example to start docker with customized meta.yaml: +``` +# Customized meta.yaml +cp src/assets/YAML/meta.yaml . +docker run -v $(pwd)/meta.yaml:/srv/assets/YAML/meta.yaml -p 8080:8080 wurstbrot/dsomm + +# Customized meta.yaml and generated.yaml +cp src/assets/YAML/meta.yaml . +cp $(pwd)/src/assets/YAML/generated/generated.yaml . +docker run -v $(pwd)/meta.yaml:/srv/assets/YAML/meta.yaml -v $(pwd)/generated.yaml:/srv/assets/YAML/generated/generated.yaml -p 8080:8080 wurstbrot/dsomm +``` + +In the corresponding [dimension YAMLs](https://github.com/devsecopsmaturitymodel/DevSecOps-MaturityModel-data/tree/main/src/assets/YAML/default), use: +``` +[...] + teamsImplemented: + Default: false + B: true + C: true + teamsEvidence: + B: All team members completed OWASP Secure Coding Dojo training on 2025-01-11. + C: | + The pentest report from 2025 has been split into Jira tasks under + [TODO-123](https://jira.example.com/issues/TODO-123). + + _2025-04-01:_ All fixes of **critical** findings are deployed to production. +``` +The `|` is yaml syntax to indicate that the evidence spans multiple lines. Markdown +syntax can be used. The evidence is currently visible on the activity from the Matrix page. # Back link -- [OWASP DevSecOps maturity model page](https://dsomm.timo-pagel.de/) +- [OWASP DevSecOps maturity model page](https://dsomm.owasp.org/) - [OWASP DevSecOps project page](https://owasp.org/www-project-devsecops-maturity-model/) - [OWASP](https://owasp.org) @@ -139,11 +179,15 @@ Multilanguage support is not given currently and not planned. # Sponsors -[![Timo Pagel IT-Consulting](https://raw.githubusercontent.com/DefectDojo/Documentation/master/doc/img/timo-pagel-logo.png)](https://pagel.pro) (Time, Logo, Icons) +[![Timo Pagel IT-Consulting](https://raw.githubusercontent.com/DefectDojo/Documentation/master/doc/img/timo-pagel-logo.png)](https://pagel.pro) + +[![Apprio Inc](https://github.com/wurstbrot/DevSecOps-MaturityModel/raw/master-old/assets/images/Apiiro_black_logo.png)](https://apiiro.com/) + +[![Heroku (hosting)](https://github.com/wurstbrot/DevSecOps-MaturityModel/raw/main/src/assets/images/sponsors/heroku.png)](https://www.heroku.com/open-source-credit-program) # Donations -You are using the model or you are inspired by it, want to help but don't want to create pull requests? You can donate at the [OWASP Project Wiki Page](https://owasp.org/donate/?reponame=www-project-devsecops-maturity-model&title=OWASP+Devsecops+Maturity+Model). Donations might be used for the design of logos/images/design or travels. +If you are using the model or you are inspired by it, want to help but don't want to create pull requests? You can donate at the [OWASP Project Wiki Page](https://owasp.org/donate/?reponame=www-project-devsecops-maturity-model&title=OWASP+Devsecops+Maturity+Model). Donations might be used for the design of logos/images/design or travels. # License @@ -151,6 +195,6 @@ This program is free software: you can redistribute it and/or modify it under th The intellectual property (content in the _data_ folder) is licensed under Attribution-ShareAlike. An example attribution by changing the content: -> This work is based on the [OWASP DevSecOps Maturity Model](https://dsomm.timo-pagel.de). +> This work is based on the [OWASP DevSecOps Maturity Model](https://dsomm.owasp.org/). -The OWASP DevSecOps Maturity Model and any contributions are Copyright © by Timo Pagel 2017-2021. +The OWASP DevSecOps Maturity Model and any contributions are Copyright © by Timo Pagel 2017-2022. diff --git a/RadarChart.js b/RadarChart.js deleted file mode 100644 index 777e354eb..000000000 --- a/RadarChart.js +++ /dev/null @@ -1,221 +0,0 @@ -//Practically all this code comes from https://github.com/alangrafu/radar-chart-d3 -//I only made some additions and aesthetic adjustments to make the chart look better -//(of course, that is only my point of view) -//Such as a better placement of the titles at each line end, -//adding numbers that reflect what each circular level stands for -//Not placing the last level and slight differences in color -// -//For a bit of extra information check the blog about it: -//http://nbremer.blogspot.nl/2013/09/making-d3-radar-chart-look-bit-better.html - -var RadarChart = { - draw: function(id, d, options){ - var cfg = { - radius: 5, - w: 600, - h: 600, - factor: 1, - factorLegend: .85, - levels: 3, - maxValue: 0, - radians: 2 * Math.PI, - opacityArea: 0.5, - ToRight: 5, - TranslateX: 80, - TranslateY: 30, - ExtraWidthX: 100, - ExtraWidthY: 100, - color: d3.scale.category10() - }; - - if('undefined' !== typeof options){ - for(var i in options){ - if('undefined' !== typeof options[i]){ - cfg[i] = options[i]; - } - } - } - cfg.maxValue = Math.max(cfg.maxValue, d3.max(d, function(i){return d3.max(i.map(function(o){return o.value;}))})); - var allAxis = (d[0].map(function(i, j){return i.axis})); - var total = allAxis.length; - var radius = cfg.factor*Math.min(cfg.w/2, cfg.h/2); - var Format = d3.format('%'); - d3.select(id).select("svg").remove(); - - var g = d3.select(id) - .append("svg") - .attr("width", cfg.w+cfg.ExtraWidthX) - .attr("height", cfg.h+cfg.ExtraWidthY) - .append("g") - .attr("transform", "translate(" + cfg.TranslateX + "," + cfg.TranslateY + ")"); - ; - - var tooltip; - - //Circular segments - for(var j=0; j +- Heatmap: Alter current bright yellow hover + +- Heatmap modal: Default: Close some tabs +- Heatmap modal: Store opened/closed tabs in local storage + +- Mapping: Add "Sort by:" +- Mapping: Fix: Sort by ISO 2017 is DESC (and 12.2) + +- Matrix: Make radio button, and use Ctrl-Click to multiple (hold click on mobile) + +# Doing +- Heatmap: Fix color calculations, to base on TeamVisible +- Heatmap: Allow non-standard team names and groups + +# Done +- Heatmap: Make heatmap the start page +- Heatmap: Center labels on sectors +- Heatmap: Fix calculations of heatmap dimension +- Heatmap: Toggle filters' visibility +- Heatmap: (Re)move Reset button +- Heatmap: Fix responsive layout diff --git a/angular.json b/angular.json new file mode 100644 index 000000000..12dfe1424 --- /dev/null +++ b/angular.json @@ -0,0 +1,121 @@ +{ + "$schema": "./node_modules/@angular/cli/lib/config/schema.json", + "version": 1, + "newProjectRoot": "projects", + "projects": { + "DSOMM": { + "projectType": "application", + "schematics": { + "@schematics/angular:application": { + "strict": true + } + }, + "root": "", + "sourceRoot": "src", + "prefix": "app", + "architect": { + "build": { + "builder": "@angular-devkit/build-angular:browser", + "options": { + "outputPath": "dist/dsomm", + "index": "src/index.html", + "main": "src/main.ts", + "polyfills": "src/polyfills.ts", + "tsConfig": "tsconfig.app.json", + "allowedCommonJsDependencies": ["yamljs"], + "assets": [ + "src/favicon.ico", + "src/assets" + ], + "styles": [ + "src/custom-theme.scss", + "src/styles.css" + ], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "1mb", + "maximumError": "3mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "6kb" + } + ], + "fileReplacements": [ + { + "replace": "src/environments/environment.ts", + "with": "src/environments/environment.prod.ts" + } + ], + "outputHashing": "all" + }, + "development": { + "buildOptimizer": false, + "optimization": false, + "vendorChunk": true, + "extractLicenses": false, + "sourceMap": true, + "namedChunks": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "builder": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "browserTarget": "DSOMM:build:production" + }, + "development": { + "browserTarget": "DSOMM:build:development" + } + }, + "defaultConfiguration": "development" + }, + "extract-i18n": { + "builder": "@angular-devkit/build-angular:extract-i18n", + "options": { + "browserTarget": "DSOMM:build" + } + }, + "test": { + "builder": "@angular-devkit/build-angular:karma", + "options": { + "main": "src/test.ts", + "polyfills": "src/polyfills.ts", + "tsConfig": "tsconfig.spec.json", + "karmaConfig": "karma.conf.js", + "assets": [ + "src/favicon.ico", + "src/assets" + ], + "styles": [ + "./node_modules/@angular/material/prebuilt-themes/indigo-pink.css", + "src/styles.css" + ], + "scripts": [] + } + }, + "lint": { + "builder": "@angular-eslint/builder:lint", + "options": { + "lintFilePatterns": [ + "src/**/*.ts", + "src/**/*.html" + ] + } + } + } + } + }, + "defaultProject": "DSOMM", + "cli": { + "defaultCollection": "@angular-eslint/schematics" + } +} diff --git a/assets/css/common.css b/assets/css/common.css deleted file mode 100644 index 5b52d14d1..000000000 --- a/assets/css/common.css +++ /dev/null @@ -1,8 +0,0 @@ - -html { - overflow-y: scroll; -} - -.form-radio { - display: inline-block; -} \ No newline at end of file diff --git a/assets/css/default.min.css b/assets/css/default.min.css deleted file mode 100644 index a75ba5ecb..000000000 --- a/assets/css/default.min.css +++ /dev/null @@ -1 +0,0 @@ -pre code{display:block;padding:.5em;background:#f0f0f0}pre code,pre .subst,pre .tag .title,pre .lisp .title,pre .clojure .built_in,pre .nginx .title{color:black}pre .string,pre .title,pre .constant,pre .parent,pre .tag .value,pre .rules .value,pre .rules .value .number,pre .preprocessor,pre .ruby .symbol,pre .ruby .symbol .string,pre .aggregate,pre .template_tag,pre .django .variable,pre .smalltalk .class,pre .addition,pre .flow,pre .stream,pre .bash .variable,pre .apache .tag,pre .apache .cbracket,pre .tex .command,pre .tex .special,pre .erlang_repl .function_or_atom,pre .markdown .header{color:#800}pre .comment,pre .annotation,pre .template_comment,pre .diff .header,pre .chunk,pre .markdown .blockquote{color:#888}pre .number,pre .date,pre .regexp,pre .literal,pre .smalltalk .symbol,pre .smalltalk .char,pre .go .constant,pre .change,pre .markdown .bullet,pre .markdown .link_url{color:#080}pre .label,pre .javadoc,pre .ruby .string,pre .decorator,pre .filter .argument,pre .localvars,pre .array,pre .attr_selector,pre .important,pre .pseudo,pre .pi,pre .doctype,pre .deletion,pre .envvar,pre .shebang,pre .apache .sqbracket,pre .nginx .built_in,pre .tex .formula,pre .erlang_repl .reserved,pre .prompt,pre .markdown .link_label,pre .vhdl .attribute,pre .clojure .attribute,pre .coffeescript .property{color:#88F}pre .keyword,pre .id,pre .phpdoc,pre .title,pre .built_in,pre .aggregate,pre .css .tag,pre .javadoctag,pre .phpdoc,pre .yardoctag,pre .smalltalk .class,pre .winutils,pre .bash .variable,pre .apache .tag,pre .go .typename,pre .tex .command,pre .markdown .strong,pre .request,pre .status{font-weight:bold}pre .markdown .emphasis{font-style:italic}pre .nginx .built_in{font-weight:normal}pre .coffeescript .javascript,pre .javascript .xml,pre .tex .formula,pre .xml .javascript,pre .xml .vbscript,pre .xml .css,pre .xml .cdata{opacity:.5} \ No newline at end of file diff --git a/assets/css/nv.d3.css b/assets/css/nv.d3.css deleted file mode 100644 index cae834827..000000000 --- a/assets/css/nv.d3.css +++ /dev/null @@ -1,769 +0,0 @@ - -/******************** - * HTML CSS - */ - - -.chartWrap { - margin: 0; - padding: 0; - overflow: hidden; -} - -/******************** - Box shadow and border radius styling -*/ -.nvtooltip.with-3d-shadow, .with-3d-shadow .nvtooltip { - -moz-box-shadow: 0 5px 10px rgba(0,0,0,.2); - -webkit-box-shadow: 0 5px 10px rgba(0,0,0,.2); - box-shadow: 0 5px 10px rgba(0,0,0,.2); - - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; -} - -/******************** - * TOOLTIP CSS - */ - -.nvtooltip { - position: absolute; - background-color: rgba(255,255,255,1.0); - padding: 1px; - border: 1px solid rgba(0,0,0,.2); - z-index: 10000; - - font-family: Arial; - font-size: 13px; - text-align: left; - pointer-events: none; - - white-space: nowrap; - - -webkit-touch-callout: none; - -webkit-user-select: none; - -khtml-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} - -/*Give tooltips that old fade in transition by - putting a "with-transitions" class on the container div. -*/ -.nvtooltip.with-transitions, .with-transitions .nvtooltip { - transition: opacity 250ms linear; - -moz-transition: opacity 250ms linear; - -webkit-transition: opacity 250ms linear; - - transition-delay: 250ms; - -moz-transition-delay: 250ms; - -webkit-transition-delay: 250ms; -} - -.nvtooltip.x-nvtooltip, -.nvtooltip.y-nvtooltip { - padding: 8px; -} - -.nvtooltip h3 { - margin: 0; - padding: 4px 14px; - line-height: 18px; - font-weight: normal; - background-color: rgba(247,247,247,0.75); - text-align: center; - - border-bottom: 1px solid #ebebeb; - - -webkit-border-radius: 5px 5px 0 0; - -moz-border-radius: 5px 5px 0 0; - border-radius: 5px 5px 0 0; -} - -.nvtooltip p { - margin: 0; - padding: 5px 14px; - text-align: center; -} - -.nvtooltip span { - display: inline-block; - margin: 2px 0; -} - -.nvtooltip table { - margin: 6px; - border-spacing:0; -} - - -.nvtooltip table td { - padding: 2px 9px 2px 0; - vertical-align: middle; -} - -.nvtooltip table td.key { - font-weight:normal; -} -.nvtooltip table td.value { - text-align: right; - font-weight: bold; -} - -.nvtooltip table tr.highlight td { - padding: 1px 9px 1px 0; - border-bottom-style: solid; - border-bottom-width: 1px; - border-top-style: solid; - border-top-width: 1px; -} - -.nvtooltip table td.legend-color-guide div { - width: 8px; - height: 8px; - vertical-align: middle; -} - -.nvtooltip .footer { - padding: 3px; - text-align: center; -} - - -.nvtooltip-pending-removal { - position: absolute; - pointer-events: none; -} - - -/******************** - * SVG CSS - */ - - -svg { - -webkit-touch-callout: none; - -webkit-user-select: none; - -khtml-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - /* Trying to get SVG to act like a greedy block in all browsers */ - display: block; - width:100%; - height:100%; -} - - -svg text { - font: normal 12px Arial; -} - -svg .title { - font: bold 14px Arial; -} - -.nvd3 .nv-background { - fill: white; - fill-opacity: 0; - /* - pointer-events: none; - */ -} - -.nvd3.nv-noData { - font-size: 18px; - font-weight: bold; -} - - -/********** -* Brush -*/ - -.nv-brush .extent { - fill-opacity: .125; - shape-rendering: crispEdges; -} - - - -/********** -* Legend -*/ - -.nvd3 .nv-legend .nv-series { - cursor: pointer; -} - -.nvd3 .nv-legend .disabled circle { - fill-opacity: 0; -} - - - -/********** -* Axes -*/ -.nvd3 .nv-axis { - pointer-events:none; -} - -.nvd3 .nv-axis path { - fill: none; - stroke: #000; - stroke-opacity: .75; - shape-rendering: crispEdges; -} - -.nvd3 .nv-axis path.domain { - stroke-opacity: .75; -} - -.nvd3 .nv-axis.nv-x path.domain { - stroke-opacity: 0; -} - -.nvd3 .nv-axis line { - fill: none; - stroke: #e5e5e5; - shape-rendering: crispEdges; -} - -.nvd3 .nv-axis .zero line, -/*this selector may not be necessary*/ .nvd3 .nv-axis line.zero { - stroke-opacity: .75; -} - -.nvd3 .nv-axis .nv-axisMaxMin text { - font-weight: bold; -} - -.nvd3 .x .nv-axis .nv-axisMaxMin text, -.nvd3 .x2 .nv-axis .nv-axisMaxMin text, -.nvd3 .x3 .nv-axis .nv-axisMaxMin text { - text-anchor: middle -} - - - -/********** -* Brush -*/ - -.nv-brush .resize path { - fill: #eee; - stroke: #666; -} - - - -/********** -* Bars -*/ - -.nvd3 .nv-bars .negative rect { - zfill: brown; -} - -.nvd3 .nv-bars rect { - zfill: steelblue; - fill-opacity: .75; - - transition: fill-opacity 250ms linear; - -moz-transition: fill-opacity 250ms linear; - -webkit-transition: fill-opacity 250ms linear; -} - -.nvd3 .nv-bars rect.hover { - fill-opacity: 1; -} - -.nvd3 .nv-bars .hover rect { - fill: lightblue; -} - -.nvd3 .nv-bars text { - fill: rgba(0,0,0,0); -} - -.nvd3 .nv-bars .hover text { - fill: rgba(0,0,0,1); -} - - -/********** -* Bars -*/ - -.nvd3 .nv-multibar .nv-groups rect, -.nvd3 .nv-multibarHorizontal .nv-groups rect, -.nvd3 .nv-discretebar .nv-groups rect { - stroke-opacity: 0; - - transition: fill-opacity 250ms linear; - -moz-transition: fill-opacity 250ms linear; - -webkit-transition: fill-opacity 250ms linear; -} - -.nvd3 .nv-multibar .nv-groups rect:hover, -.nvd3 .nv-multibarHorizontal .nv-groups rect:hover, -.nvd3 .nv-discretebar .nv-groups rect:hover { - fill-opacity: 1; -} - -.nvd3 .nv-discretebar .nv-groups text, -.nvd3 .nv-multibarHorizontal .nv-groups text { - font-weight: bold; - fill: rgba(0,0,0,1); - stroke: rgba(0,0,0,0); -} - -/*********** -* Pie Chart -*/ - -.nvd3.nv-pie path { - stroke-opacity: 0; - transition: fill-opacity 250ms linear, stroke-width 250ms linear, stroke-opacity 250ms linear; - -moz-transition: fill-opacity 250ms linear, stroke-width 250ms linear, stroke-opacity 250ms linear; - -webkit-transition: fill-opacity 250ms linear, stroke-width 250ms linear, stroke-opacity 250ms linear; - -} - -.nvd3.nv-pie .nv-slice text { - stroke: #000; - stroke-width: 0; -} - -.nvd3.nv-pie path { - stroke: #fff; - stroke-width: 1px; - stroke-opacity: 1; -} - -.nvd3.nv-pie .hover path { - fill-opacity: .7; -} -.nvd3.nv-pie .nv-label { - pointer-events: none; -} -.nvd3.nv-pie .nv-label rect { - fill-opacity: 0; - stroke-opacity: 0; -} - -/********** -* Lines -*/ - -.nvd3 .nv-groups path.nv-line { - fill: none; - stroke-width: 1.5px; - /* - stroke-linecap: round; - shape-rendering: geometricPrecision; - - transition: stroke-width 250ms linear; - -moz-transition: stroke-width 250ms linear; - -webkit-transition: stroke-width 250ms linear; - - transition-delay: 250ms - -moz-transition-delay: 250ms; - -webkit-transition-delay: 250ms; - */ -} - -.nvd3 .nv-groups path.nv-line.nv-thin-line { - stroke-width: 1px; -} - - -.nvd3 .nv-groups path.nv-area { - stroke: none; - /* - stroke-linecap: round; - shape-rendering: geometricPrecision; - - stroke-width: 2.5px; - transition: stroke-width 250ms linear; - -moz-transition: stroke-width 250ms linear; - -webkit-transition: stroke-width 250ms linear; - - transition-delay: 250ms - -moz-transition-delay: 250ms; - -webkit-transition-delay: 250ms; - */ -} - -.nvd3 .nv-line.hover path { - stroke-width: 6px; -} - -/* -.nvd3.scatter .groups .point { - fill-opacity: 0.1; - stroke-opacity: 0.1; -} - */ - -.nvd3.nv-line .nvd3.nv-scatter .nv-groups .nv-point { - fill-opacity: 0; - stroke-opacity: 0; -} - -.nvd3.nv-scatter.nv-single-point .nv-groups .nv-point { - fill-opacity: .5 !important; - stroke-opacity: .5 !important; -} - - -.with-transitions .nvd3 .nv-groups .nv-point { - transition: stroke-width 250ms linear, stroke-opacity 250ms linear; - -moz-transition: stroke-width 250ms linear, stroke-opacity 250ms linear; - -webkit-transition: stroke-width 250ms linear, stroke-opacity 250ms linear; - -} - -.nvd3.nv-scatter .nv-groups .nv-point.hover, -.nvd3 .nv-groups .nv-point.hover { - stroke-width: 7px; - fill-opacity: .95 !important; - stroke-opacity: .95 !important; -} - - -.nvd3 .nv-point-paths path { - stroke: #aaa; - stroke-opacity: 0; - fill: #eee; - fill-opacity: 0; -} - - - -.nvd3 .nv-indexLine { - cursor: ew-resize; -} - - -/********** -* Distribution -*/ - -.nvd3 .nv-distribution { - pointer-events: none; -} - - - -/********** -* Scatter -*/ - -/* **Attempting to remove this for useVoronoi(false), need to see if it's required anywhere -.nvd3 .nv-groups .nv-point { - pointer-events: none; -} -*/ - -.nvd3 .nv-groups .nv-point.hover { - stroke-width: 20px; - stroke-opacity: .5; -} - -.nvd3 .nv-scatter .nv-point.hover { - fill-opacity: 1; -} - -/* -.nv-group.hover .nv-point { - fill-opacity: 1; -} -*/ - - -/********** -* Stacked Area -*/ - -.nvd3.nv-stackedarea path.nv-area { - fill-opacity: .7; - /* - stroke-opacity: .65; - fill-opacity: 1; - */ - stroke-opacity: 0; - - transition: fill-opacity 250ms linear, stroke-opacity 250ms linear; - -moz-transition: fill-opacity 250ms linear, stroke-opacity 250ms linear; - -webkit-transition: fill-opacity 250ms linear, stroke-opacity 250ms linear; - - /* - transition-delay: 500ms; - -moz-transition-delay: 500ms; - -webkit-transition-delay: 500ms; - */ - -} - -.nvd3.nv-stackedarea path.nv-area.hover { - fill-opacity: .9; - /* - stroke-opacity: .85; - */ -} -/* -.d3stackedarea .groups path { - stroke-opacity: 0; -} - */ - - - -.nvd3.nv-stackedarea .nv-groups .nv-point { - stroke-opacity: 0; - fill-opacity: 0; -} - -/* -.nvd3.nv-stackedarea .nv-groups .nv-point.hover { - stroke-width: 20px; - stroke-opacity: .75; - fill-opacity: 1; -}*/ - - - -/********** -* Line Plus Bar -*/ - -.nvd3.nv-linePlusBar .nv-bar rect { - fill-opacity: .75; -} - -.nvd3.nv-linePlusBar .nv-bar rect:hover { - fill-opacity: 1; -} - - -/********** -* Bullet -*/ - -.nvd3.nv-bullet { font: 10px sans-serif; } -.nvd3.nv-bullet .nv-measure { fill-opacity: .8; } -.nvd3.nv-bullet .nv-measure:hover { fill-opacity: 1; } -.nvd3.nv-bullet .nv-marker { stroke: #000; stroke-width: 2px; } -.nvd3.nv-bullet .nv-markerTriangle { stroke: #000; fill: #fff; stroke-width: 1.5px; } -.nvd3.nv-bullet .nv-tick line { stroke: #666; stroke-width: .5px; } -.nvd3.nv-bullet .nv-range.nv-s0 { fill: #eee; } -.nvd3.nv-bullet .nv-range.nv-s1 { fill: #ddd; } -.nvd3.nv-bullet .nv-range.nv-s2 { fill: #ccc; } -.nvd3.nv-bullet .nv-title { font-size: 14px; font-weight: bold; } -.nvd3.nv-bullet .nv-subtitle { fill: #999; } - - -.nvd3.nv-bullet .nv-range { - fill: #bababa; - fill-opacity: .4; -} -.nvd3.nv-bullet .nv-range:hover { - fill-opacity: .7; -} - - - -/********** -* Sparkline -*/ - -.nvd3.nv-sparkline path { - fill: none; -} - -.nvd3.nv-sparklineplus g.nv-hoverValue { - pointer-events: none; -} - -.nvd3.nv-sparklineplus .nv-hoverValue line { - stroke: #333; - stroke-width: 1.5px; - } - -.nvd3.nv-sparklineplus, -.nvd3.nv-sparklineplus g { - pointer-events: all; -} - -.nvd3 .nv-hoverArea { - fill-opacity: 0; - stroke-opacity: 0; -} - -.nvd3.nv-sparklineplus .nv-xValue, -.nvd3.nv-sparklineplus .nv-yValue { - /* - stroke: #666; - */ - stroke-width: 0; - font-size: .9em; - font-weight: normal; -} - -.nvd3.nv-sparklineplus .nv-yValue { - stroke: #f66; -} - -.nvd3.nv-sparklineplus .nv-maxValue { - stroke: #2ca02c; - fill: #2ca02c; -} - -.nvd3.nv-sparklineplus .nv-minValue { - stroke: #d62728; - fill: #d62728; -} - -.nvd3.nv-sparklineplus .nv-currentValue { - /* - stroke: #444; - fill: #000; - */ - font-weight: bold; - font-size: 1.1em; -} - -/********** -* historical stock -*/ - -.nvd3.nv-ohlcBar .nv-ticks .nv-tick { - stroke-width: 2px; -} - -.nvd3.nv-ohlcBar .nv-ticks .nv-tick.hover { - stroke-width: 4px; -} - -.nvd3.nv-ohlcBar .nv-ticks .nv-tick.positive { - stroke: #2ca02c; -} - -.nvd3.nv-ohlcBar .nv-ticks .nv-tick.negative { - stroke: #d62728; -} - -.nvd3.nv-historicalStockChart .nv-axis .nv-axislabel { - font-weight: bold; -} - -.nvd3.nv-historicalStockChart .nv-dragTarget { - fill-opacity: 0; - stroke: none; - cursor: move; -} - -.nvd3 .nv-brush .extent { - /* - cursor: ew-resize !important; - */ - fill-opacity: 0 !important; -} - -.nvd3 .nv-brushBackground rect { - stroke: #000; - stroke-width: .4; - fill: #fff; - fill-opacity: .7; -} - - - -/********** -* Indented Tree -*/ - - -/** - * TODO: the following 3 selectors are based on classes used in the example. I should either make them standard and leave them here, or move to a CSS file not included in the library - */ -.nvd3.nv-indentedtree .name { - margin-left: 5px; -} - -.nvd3.nv-indentedtree .clickable { - color: #08C; - cursor: pointer; -} - -.nvd3.nv-indentedtree span.clickable:hover { - color: #005580; - text-decoration: underline; -} - - -.nvd3.nv-indentedtree .nv-childrenCount { - display: inline-block; - margin-left: 5px; -} - -.nvd3.nv-indentedtree .nv-treeicon { - cursor: pointer; - /* - cursor: n-resize; - */ -} - -.nvd3.nv-indentedtree .nv-treeicon.nv-folded { - cursor: pointer; - /* - cursor: s-resize; - */ -} - -/********** -* Parallel Coordinates -*/ - -.nvd3 .background path { - fill: none; - stroke: #ccc; - stroke-opacity: .4; - shape-rendering: crispEdges; -} - -.nvd3 .foreground path { - fill: none; - stroke: steelblue; - stroke-opacity: .7; -} - -.nvd3 .brush .extent { - fill-opacity: .3; - stroke: #fff; - shape-rendering: crispEdges; -} - -.nvd3 .axis line, .axis path { - fill: none; - stroke: #000; - shape-rendering: crispEdges; -} - -.nvd3 .axis text { - text-shadow: 0 1px 0 #fff; -} - -/**** -Interactive Layer -*/ -.nvd3 .nv-interactiveGuideLine { - pointer-events:none; -} -.nvd3 line.nv-guideline { - stroke: #ccc; -} \ No newline at end of file diff --git a/assets/images/Build and Deployment.png b/assets/images/Build and Deployment.png deleted file mode 100644 index 57a5af7ff..000000000 Binary files a/assets/images/Build and Deployment.png and /dev/null differ diff --git a/assets/images/Culture and Organization.png b/assets/images/Culture and Organization.png deleted file mode 100644 index 0c2c83de4..000000000 Binary files a/assets/images/Culture and Organization.png and /dev/null differ diff --git a/assets/images/Implementation.png b/assets/images/Implementation.png deleted file mode 100644 index 799b3275d..000000000 Binary files a/assets/images/Implementation.png and /dev/null differ diff --git a/assets/images/Information Gathering.png b/assets/images/Information Gathering.png deleted file mode 100644 index 2ee3df555..000000000 Binary files a/assets/images/Information Gathering.png and /dev/null differ diff --git a/assets/images/Test and Verification.png b/assets/images/Test and Verification.png deleted file mode 100644 index 7c987ae7d..000000000 Binary files a/assets/images/Test and Verification.png and /dev/null differ diff --git a/assets/js/bootstrap.min.js b/assets/js/bootstrap.min.js deleted file mode 100644 index e0b220f40..000000000 --- a/assets/js/bootstrap.min.js +++ /dev/null @@ -1,7 +0,0 @@ -/** -* Bootstrap.js by @fat & @mdo -* plugins: bootstrap-transition.js, bootstrap-modal.js, bootstrap-dropdown.js, bootstrap-scrollspy.js, bootstrap-tab.js, bootstrap-tooltip.js, bootstrap-popover.js, bootstrap-affix.js, bootstrap-alert.js, bootstrap-button.js, bootstrap-collapse.js, bootstrap-carousel.js, bootstrap-typeahead.js -* Copyright 2012 Twitter, Inc. -* http://www.apache.org/licenses/LICENSE-2.0.txt -*/ -!function(a){a(function(){a.support.transition=function(){var a=function(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"},c;for(c in b)if(a.style[c]!==undefined)return b[c]}();return a&&{end:a}}()})}(window.jQuery),!function(a){var b=function(b,c){this.options=c,this.$element=a(b).delegate('[data-dismiss="modal"]',"click.dismiss.modal",a.proxy(this.hide,this)),this.options.remote&&this.$element.find(".modal-body").load(this.options.remote)};b.prototype={constructor:b,toggle:function(){return this[this.isShown?"hide":"show"]()},show:function(){var b=this,c=a.Event("show");this.$element.trigger(c);if(this.isShown||c.isDefaultPrevented())return;a("body").addClass("modal-open"),this.isShown=!0,this.escape(),this.backdrop(function(){var c=a.support.transition&&b.$element.hasClass("fade");b.$element.parent().length||b.$element.appendTo(document.body),b.$element.show(),c&&b.$element[0].offsetWidth,b.$element.addClass("in").attr("aria-hidden",!1).focus(),b.enforceFocus(),c?b.$element.one(a.support.transition.end,function(){b.$element.trigger("shown")}):b.$element.trigger("shown")})},hide:function(b){b&&b.preventDefault();var c=this;b=a.Event("hide"),this.$element.trigger(b);if(!this.isShown||b.isDefaultPrevented())return;this.isShown=!1,a("body").removeClass("modal-open"),this.escape(),a(document).off("focusin.modal"),this.$element.removeClass("in").attr("aria-hidden",!0),a.support.transition&&this.$element.hasClass("fade")?this.hideWithTransition():this.hideModal()},enforceFocus:function(){var b=this;a(document).on("focusin.modal",function(a){b.$element[0]!==a.target&&!b.$element.has(a.target).length&&b.$element.focus()})},escape:function(){var a=this;this.isShown&&this.options.keyboard?this.$element.on("keyup.dismiss.modal",function(b){b.which==27&&a.hide()}):this.isShown||this.$element.off("keyup.dismiss.modal")},hideWithTransition:function(){var b=this,c=setTimeout(function(){b.$element.off(a.support.transition.end),b.hideModal()},500);this.$element.one(a.support.transition.end,function(){clearTimeout(c),b.hideModal()})},hideModal:function(a){this.$element.hide().trigger("hidden"),this.backdrop()},removeBackdrop:function(){this.$backdrop.remove(),this.$backdrop=null},backdrop:function(b){var c=this,d=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var e=a.support.transition&&d;this.$backdrop=a('