├── .github └── workflows │ ├── build.yaml │ └── semgrep.yaml ├── .gitignore ├── Dockerfile ├── LICENSE ├── README.md ├── action.yml ├── docs ├── README.md └── TM-using-LLMs.05.2024.pdf ├── entrypoint.sh └── scripts └── bump-action-version.sh /.github/workflows/build.yaml: -------------------------------------------------------------------------------- 1 | name: Docker 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | 9 | steps: 10 | - uses: actions/checkout@v3 11 | - name: Dockefile linter 12 | uses: hadolint/hadolint-action@v3.1.0 13 | with: 14 | dockerfile: Dockerfile 15 | -------------------------------------------------------------------------------- /.github/workflows/semgrep.yaml: -------------------------------------------------------------------------------- 1 | # Name of this GitHub Actions workflow. 2 | name: Semgrep 3 | 4 | on: 5 | # Scan changed files in PRs (diff-aware scanning): 6 | pull_request: {} 7 | # Scan on-demand through GitHub Actions interface: 8 | workflow_dispatch: {} 9 | # Scan mainline branches and report all findings: 10 | push: 11 | branches: ["main"] 12 | # Schedule the CI job (this method uses cron syntax): 13 | schedule: 14 | - cron: '20 17 * * *' # Sets Semgrep to scan every day at 17:20 UTC. 15 | # It is recommended to change the schedule to a random time. 16 | 17 | jobs: 18 | semgrep: 19 | # User definable name of this GitHub Actions job. 20 | name: semgrep/ci 21 | # If you are self-hosting, change the following `runs-on` value: 22 | runs-on: ubuntu-latest 23 | 24 | container: 25 | # A Docker image with Semgrep installed. Do not change this. 26 | image: returntocorp/semgrep 27 | 28 | # Skip any PR created by dependabot to avoid permission issues: 29 | if: (github.actor != 'dependabot[bot]') 30 | 31 | steps: 32 | # Fetch project source with GitHub Actions Checkout. 33 | - uses: actions/checkout@v3 34 | # Run the "semgrep ci" command on the command line of the docker image. 35 | - run: semgrep ci 36 | env: 37 | # Connect to Semgrep Cloud Platform through your SEMGREP_APP_TOKEN. 38 | # Generate a token from Semgrep Cloud Platform > Settings 39 | # and add it to your GitHub secrets. 40 | SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }} -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | share/python-wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | MANIFEST 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .nox/ 43 | .coverage 44 | .coverage.* 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | *.cover 49 | *.py,cover 50 | .hypothesis/ 51 | .pytest_cache/ 52 | cover/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | .pybuilder/ 76 | target/ 77 | 78 | # Jupyter Notebook 79 | .ipynb_checkpoints 80 | 81 | # IPython 82 | profile_default/ 83 | ipython_config.py 84 | 85 | # pyenv 86 | # For a library or package, you might want to ignore these files since the code is 87 | # intended to run in multiple environments; otherwise, check them in: 88 | # .python-version 89 | 90 | # pipenv 91 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 92 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 93 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 94 | # install all needed dependencies. 95 | #Pipfile.lock 96 | 97 | # poetry 98 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 99 | # This is especially recommended for binary packages to ensure reproducibility, and is more 100 | # commonly ignored for libraries. 101 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 102 | #poetry.lock 103 | 104 | # pdm 105 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. 106 | #pdm.lock 107 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it 108 | # in version control. 109 | # https://pdm.fming.dev/#use-with-ide 110 | .pdm.toml 111 | 112 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm 113 | __pypackages__/ 114 | 115 | # Celery stuff 116 | celerybeat-schedule 117 | celerybeat.pid 118 | 119 | # SageMath parsed files 120 | *.sage.py 121 | 122 | # Environments 123 | .env 124 | .venv 125 | env/ 126 | venv/ 127 | ENV/ 128 | env.bak/ 129 | venv.bak/ 130 | 131 | # Spyder project settings 132 | .spyderproject 133 | .spyproject 134 | 135 | # Rope project settings 136 | .ropeproject 137 | 138 | # mkdocs documentation 139 | /site 140 | 141 | # mypy 142 | .mypy_cache/ 143 | .dmypy.json 144 | dmypy.json 145 | 146 | # Pyre type checker 147 | .pyre/ 148 | 149 | # pytype static type analyzer 150 | .pytype/ 151 | 152 | # Cython debug symbols 153 | cython_debug/ 154 | 155 | # PyCharm 156 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can 157 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 158 | # and can be added to the global gitignore or merged into this file. For a more nuclear 159 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 160 | #.idea/ 161 | 162 | .vscode 163 | .ruff_cache -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # 3.11.7-alpine 2 | FROM python@sha256:84271da1cd297b01dd4706e01e7789b08b54a5a512c0e3fcaf11c902640f5ebd 3 | 4 | ENV AI_THREAT_MODELING_VERSION=1.1.5 5 | 6 | WORKDIR /app 7 | 8 | RUN wget -q -O ai-threat-modeling.tar.gz "https://github.com/xvnpw/ai-threat-modeling/archive/refs/tags/v${AI_THREAT_MODELING_VERSION}.tar.gz" && \ 9 | tar -xzvf ai-threat-modeling.tar.gz && \ 10 | rm ai-threat-modeling.tar.gz && \ 11 | mv "ai-threat-modeling-${AI_THREAT_MODELING_VERSION}" ai-threat-modeling 12 | 13 | WORKDIR /app/ai-threat-modeling 14 | RUN pip install --no-cache-dir -r requirements.txt 15 | 16 | # Copies your code file from your action repository to the filesystem path `/` of the container 17 | COPY entrypoint.sh /entrypoint.sh 18 | 19 | # Code file to execute when the docker container starts up (`entrypoint.sh`) 20 | ENTRYPOINT ["/entrypoint.sh"] 21 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 xvnpw 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ⚠️ This repository is deprecated and will be archived. All prompts moved to: https://github.com/xvnpw/fabric-agent-action 2 | 3 | # AI Threat Modeling action 4 | 5 | [![Docker](https://github.com/xvnpw/ai-threat-modeling-action/actions/workflows/build.yaml/badge.svg)](https://github.com/xvnpw/ai-threat-modeling-action/actions/workflows/build.yaml) 6 | 7 | 🤖 You can use this GitHub Action to generate AI featured content for threat modeling and security review. It uses [xvnpw/ai-threat-modeling](https://github.com/xvnpw/ai-threat-modeling) underneath. 8 | 9 | > ⚠️ This is experimental project 10 | 11 | Supported features: 12 | | Feature | Description | 13 | | --- | --- | 14 | | High Level Security and Privacy Requirements | Action will take project description and will use LLM to generate high level requirements regarding security and privacy | 15 | | Threat Model of Architecture | Action will take architecture description and will use LLM to generate threat model for it | 16 | | Security Acceptance Criteria for User Story | Action will take particular user story and generate security related acceptance criteria | 17 | | Review of input file | Action will take input file (e.g. Architecture Description) are review it using LLM | 18 | 19 | Table of content 20 | =============== 21 | * [Versions](#versions) 22 | * [Example Outputs](#example-outputs) 23 | * [Feature: High Level Security and Privacy Requirements](#feature-high-level-security-and-privacy-requirements) 24 | * [Feature: Threat Model of Architecture](#feature-threat-model-of-architecture) 25 | * [Feature: Security Acceptance Criteria for User Story](#feature-security-acceptance-criteria-for-user-story) 26 | * [Feature: Review of input file](#feature-review-of-input-file) 27 | * [Inputs](#inputs) 28 | * [LLM Providers](#llm-providers) 29 | * [Usage](#usage) 30 | * [High Level Security and Privacy Requirements](#high-level-security-and-privacy-requirements) 31 | * [Architecture Threat Model](#architecture-threat-model) 32 | * [Security Acceptance Criteria for User Story](#security-acceptance-criteria-for-user-story) 33 | * [Trigger on changes to directory](#trigger-on-changes-to-directory) 34 | * [Trigger on issue change](#trigger-on-issue-change) 35 | * [Review of input file](#review-of-input-file) 36 | * [Push into Repository](#push-into-repository) 37 | * [Create Pull Request](#create-pull-request) 38 | * [Custom Prompts](#custom-prompts) 39 | * [Roadmap](#-roadmap) 40 | * [Tech Stack](#-tech-stack) 41 | * [Fork](#fork) 42 | * [Privacy](#privacy) 43 | * [OpenAI](#openai) 44 | * [OpenRouter](#openrouter) 45 | 46 | ## Versions 47 | 48 | Use below versions for specific models: 49 | 50 | | Model | Version | Note | 51 | | --- | --- | --- | 52 | | OpenAI GPT-3.5, Anthropic Claude 2 | v1.2.6.1 | ⚠️ Latest releases include prompts that might not work properly with those models | 53 | | OpenAI GPT-4 | Latest | 54 | | Claude 3 | Latest | 55 | 56 | ## Example Outputs 57 | 58 | ### Feature: High Level Security and Privacy Requirements 59 | 60 | | Model | Input | Output | 61 | | --- | --- | --- | 62 | | **OpenAI GPT-3.5** | [PROJECT.md](https://github.com/xvnpw/ai-nutrition-pro-design-gpt3.5/blob/main/PROJECT.md) | [PROJECT_SECURITY.md](https://github.com/xvnpw/ai-nutrition-pro-design-gpt3.5/blob/main/PROJECT_SECURITY.md) or as [pull request](https://github.com/xvnpw/ai-nutrition-pro-design-gpt3.5/pull/2) | 63 | | **Anthropic Claude 2** | [PROJECT.md](https://github.com/xvnpw/ai-nutrition-pro-design-claude2/blob/main/PROJECT.md) | [PROJECT_SECURITY.md](https://github.com/xvnpw/ai-nutrition-pro-design-claude2/blob/main/PROJECT_SECURITY.md) or as [pull request](https://github.com/xvnpw/ai-nutrition-pro-design-claude2/pull/1) | 64 | | **OpenAI GPT-4** | [PROJECT.md](https://github.com/xvnpw/ai-nutrition-pro-design-gpt4/blob/main/PROJECT.md) | [PROJECT_SECURITY.md](https://github.com/xvnpw/ai-nutrition-pro-design-gpt4/blob/main/PROJECT_SECURITY.md) or as [pull request](https://github.com/xvnpw/ai-nutrition-pro-design-gpt4/pull/2) | 65 | | **Anthropic Claude 3 Opus** | [PROJECT.md](https://github.com/xvnpw/ai-nutrition-pro-design-claude3-opus/blob/main/PROJECT.md) | [PROJECT_SECURITY.md](https://github.com/xvnpw/ai-nutrition-pro-design-claude3-opus/blob/main/PROJECT_SECURITY.md) or as [pull request](https://github.com/xvnpw/ai-nutrition-pro-design-claude3-opus/pull/2) | 66 | 67 | ### Feature: Threat Model of Architecture 68 | 69 | | Model | Input | Output | 70 | | --- | --- | --- | 71 | | **OpenAI GPT-3.5** | [ARCHITECTURE.md](https://github.com/xvnpw/ai-nutrition-pro-design-gpt3.5/blob/main/ARCHITECTURE.md) | [ARCHITECTURE_SECURITY.md](https://github.com/xvnpw/ai-nutrition-pro-design-gpt3.5/blob/main/ARCHITECTURE_SECURITY.md) | 72 | | **Anthropic Claude 2** | [ARCHITECTURE.md](https://github.com/xvnpw/ai-nutrition-pro-design-claude2/blob/main/ARCHITECTURE.md) | [ARCHITECTURE_SECURITY.md](https://github.com/xvnpw/ai-nutrition-pro-design-claude2/blob/main/ARCHITECTURE_SECURITY.md) | 73 | | **OpenAI GPT-4** | [ARCHITECTURE.md](https://github.com/xvnpw/ai-nutrition-pro-design-gpt4/blob/main/ARCHITECTURE.md) | [ARCHITECTURE_SECURITY.md](https://github.com/xvnpw/ai-nutrition-pro-design-gpt4/blob/main/ARCHITECTURE_SECURITY.md) | 74 | | **Anthropic Claude 3 Opus** | [ARCHITECTURE.md](https://github.com/xvnpw/ai-nutrition-pro-design-claude3-opus/blob/main/ARCHITECTURE.md) | [ARCHITECTURE_SECURITY.md](https://github.com/xvnpw/ai-nutrition-pro-design-claude3-opus/blob/main/ARCHITECTURE_SECURITY.md) | 75 | 76 | ### Feature: Security Acceptance Criteria for User Story 77 | 78 | | Model | Input | Output | 79 | | --- | --- | --- | 80 | | **OpenAI GPT-3.5** | [0001_STORE_DIET_INTRODUCTIONS.md](https://github.com/xvnpw/ai-nutrition-pro-design-gpt3.5/blob/main/user-stories/0001_STORE_DIET_INTRODUCTIONS.md) or [issue](https://github.com/xvnpw/ai-nutrition-pro-design-gpt3.5/issues/1) | [0001_STORE_DIET_INTRODUCTIONS_SECURITY.md](https://github.com/xvnpw/ai-nutrition-pro-design-gpt3.5/blob/main/user-stories/0001_STORE_DIET_INTRODUCTIONS_SECURITY.md) or as [issue comment](https://github.com/xvnpw/ai-nutrition-pro-design-gpt3.5/issues/1) | 81 | | **Anthropic Claude 2** | [0001_STORE_DIET_INTRODUCTIONS.md](https://github.com/xvnpw/ai-nutrition-pro-design-claude2/blob/main/user-stories/0001_STORE_DIET_INTRODUCTIONS.md) or [issue](https://github.com/xvnpw/ai-nutrition-pro-design-claude2/issues/2) | [0001_STORE_DIET_INTRODUCTIONS_SECURITY.md](https://github.com/xvnpw/ai-nutrition-pro-design-claude2/blob/main/user-stories/0001_STORE_DIET_INTRODUCTIONS_SECURITY.md) or as [issue comment](https://github.com/xvnpw/ai-nutrition-pro-design-claude2/issues/2) | 82 | | **OpenAI GPT-4** | [0001_STORE_DIET_INTRODUCTIONS.md](https://github.com/xvnpw/ai-nutrition-pro-design-gpt4/blob/main/user-stories/0001_STORE_DIET_INTRODUCTIONS.md) or [issue](https://github.com/xvnpw/ai-nutrition-pro-design-gpt4/issues/1) | [0001_STORE_DIET_INTRODUCTIONS_SECURITY.md](https://github.com/xvnpw/ai-nutrition-pro-design-gpt4/blob/main/user-stories/0001_STORE_DIET_INTRODUCTIONS_SECURITY.md) or as [issue comment](https://github.com/xvnpw/ai-nutrition-pro-design-gpt4/issues/1) | 83 | | **Anthropic Claude 3 Opus** | [0001_STORE_DIET_INTRODUCTIONS.md](https://github.com/xvnpw/ai-nutrition-pro-design-claude3-opus/blob/main/user-stories/0001_STORE_DIET_INTRODUCTIONS.md) or [issue](https://github.com/xvnpw/ai-nutrition-pro-design-claude3-opus/issues/1) | [0001_STORE_DIET_INTRODUCTIONS_SECURITY.md](https://github.com/xvnpw/ai-nutrition-pro-design-claude3-opus/blob/main/user-stories/0001_STORE_DIET_INTRODUCTIONS_SECURITY.md) or as [issue comment](https://github.com/xvnpw/ai-nutrition-pro-design-claude3-opus/issues/1) | 84 | 85 | ### Feature: Review of input file 86 | 87 | | Model | Input | Output | 88 | | --- | --- | --- | 89 | | **OpenAI GPT-4** | [ARCHITECTURE.md](https://github.com/xvnpw/ai-nutrition-pro-design-gpt4/blob/main/ARCHITECTURE.md) | [ARCHITECTURE_REVIEW.md](https://github.com/xvnpw/ai-nutrition-pro-design-gpt4/blob/main/ARCHITECTURE_REVIEW.md) | 90 | | **Anthropic Claude 3 Opus** | [ARCHITECTURE.md](https://github.com/xvnpw/ai-nutrition-pro-design-claude3-opus/blob/main/ARCHITECTURE.md) | [ARCHITECTURE_REVIEW.md](https://github.com/xvnpw/ai-nutrition-pro-design-claude3-opus/blob/main/ARCHITECTURE_REVIEW.md) | 91 | 92 | ## Inputs 93 | 94 | Add a step like this to your workflow: 95 | 96 | ```yaml 97 | - uses: xvnpw/ai-threat-modeling-action@v1.3.4 # You can change this to use a specific version. 98 | with: 99 | # Type of feature, one of: project, architecture, user-story 100 | # Default: '' 101 | # Required 102 | type: 'project' 103 | 104 | # Provider name, one of: openai, openrouter 105 | # Default: 'openai' 106 | provider: 'openai' 107 | 108 | # Paths to input files formatted as json array 109 | # Default: '' 110 | input_files: '["PROJECT.md"]' 111 | 112 | # Path to output file 113 | # Default: '' 114 | output_file: 'PROJECT_SECURITY.md' 115 | 116 | # For USER STORY only! paths to architecture files formatted as json array 117 | # Default: '' 118 | input_architecture_files: '["ARCHITECTURE.md"]' 119 | 120 | # For USER STORY only! path to architecture threat model 121 | # Default: '' 122 | input_architecture_threat_model_file: 'ARCHITECTURE_SECURITY.md' 123 | 124 | # For USER STORY only! suffix that will be added to input file name to create output file 125 | # Default: '_SECURITY' 126 | user_story_output_suffix: '_SECURITY' 127 | 128 | # Type of OpenAI GPT model 129 | # Default: gpt-4 130 | # For openai models check: https://platform.openai.com/account/rate-limits 131 | # For openrouter models check: https://openrouter.ai/docs#models 132 | model: 'gpt-3.5-turbo-16k' 133 | 134 | # Sampling temperature for a model 135 | # Default: 0 136 | temperature: '0.3' 137 | 138 | # Review input files using LLM 139 | # Default: false 140 | review: true 141 | 142 | # Verbose log messages 143 | # Default: false 144 | verbose: true 145 | 146 | # Debug log messages 147 | # Default: false 148 | debug: true 149 | 150 | # Prompt templates directory 151 | # Default: '/app/templates' 152 | # By default action will use prompt templates build-in docker image. You can specify your own without forking action. 153 | templates_dir: './templates' 154 | env: 155 | # OpenAI API key 156 | # Optional. Only if want to use openai provider 157 | # Get a key from https://platform.openai.com/account/api-keys 158 | # Add it to secrets in your repository settings 159 | OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} 160 | 161 | # Open Router API key 162 | # Optional. Only if want to use openrouter provider 163 | # Get a key from https://openrouter.ai/keys 164 | # Add it to secrets in your repository settings 165 | OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }} 166 | ``` 167 | 168 | ## LLM Providers 169 | 170 | Currently supporting: 171 | - [OpenAI](https://platform.openai.com/) 172 | - [OpenRouter](https://openrouter.ai/) 173 | 174 | ## Usage 175 | 176 | Action will generate `output_file` based on inputs. Using other actions you can: 177 | - directly [push](#push-into-repository) into repository, 178 | - create [pull request](#create-pull-request), 179 | - or add comment to [issue](#trigger-on-issue-change). 180 | 181 | ### High Level Security and Privacy Requirements 182 | 183 | If your input files are quite big you need to change `model` to one with bigger context, e.g. `gpt-3.5-turbo-16k`. 184 | 185 | If you change input files, remember to change the trigger: 186 | ```yaml 187 | on: 188 | push: 189 | branches: 190 | - main 191 | paths: 192 | - 'project-desc-1.md' 193 | - 'project-desc-2.md' 194 | ``` 195 | 196 | **Example (pull requests approach):** 197 | 198 | ```yaml 199 | on: 200 | push: 201 | branches: 202 | - main 203 | paths: 204 | - 'PROJECT.md' 205 | 206 | jobs: 207 | project_ai_devsecops_job: 208 | runs-on: ubuntu-latest 209 | 210 | permissions: 211 | # Give the default GITHUB_TOKEN write permission to commit and push the 212 | # added or changed files to the repository. Also permission to create/update 213 | # pull requests. 214 | contents: write 215 | pull-requests: write 216 | 217 | name: Run ai threat modeling action for project analysis 218 | steps: 219 | - name: Checkout repo 220 | uses: actions/checkout@v3 221 | - name: Generate project security requirements 222 | uses: xvnpw/ai-threat-modeling-action@v1.3.4 223 | with: 224 | type: 'project' 225 | input_files: '["PROJECT.md"]' 226 | output_file: 'PROJECT_SECURITY.md' 227 | temperature: 0 228 | verbose: true 229 | env: 230 | OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} 231 | # Will use peter-evans/create-pull-request to create or update pull request 232 | - name: Create Pull Request 233 | uses: peter-evans/create-pull-request@v5 234 | with: 235 | branch: create-pull-request/project 236 | title: (AI Generated) High Level Security and Privacy Requirements 237 | body: Automated pull request based on your changes to project. Please review it carefully. 238 | labels: 'security, ai' 239 | ``` 240 | 241 | ### Architecture Threat Model 242 | 243 | Check [High Level Security and Privacy Requirements](#high-level-security-and-privacy-requirements) for details about triggers and models. 244 | 245 | **Example (direct push into repository):** 246 | 247 | ```yaml 248 | on: 249 | push: 250 | branches: 251 | - main 252 | paths: 253 | - 'ARCHITECTURE.md' 254 | 255 | jobs: 256 | architecture_ai_tm_job: 257 | runs-on: ubuntu-latest 258 | 259 | permissions: 260 | # Give the default GITHUB_TOKEN write permission to commit and push the 261 | # added or changed files to the repository. 262 | contents: write 263 | 264 | name: Will run ai threat modeling action for architecture analysis 265 | steps: 266 | - name: Checkout repo 267 | uses: actions/checkout@v3 268 | - name: Generate architecture threat model 269 | uses: xvnpw/ai-threat-modeling-action@v1.3.4 270 | with: 271 | type: 'architecture' 272 | input_files: '["ARCHITECTURE.md"]' 273 | output_file: 'ARCHITECTURE_SECURITY.md' 274 | temperature: 0 275 | verbose: true 276 | env: 277 | OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} 278 | # Will use add-and-commit action to push output_file directly into repository 279 | - name: Commit changes 280 | uses: EndBug/add-and-commit@v9 281 | with: 282 | message: 'Project architecture threat model' 283 | add: 'ARCHITECTURE_SECURITY.md' 284 | ``` 285 | 286 | ### Security Acceptance Criteria for User Story 287 | 288 | Most useful usage is with [github issues](https://github.com/features/issues). But you can also generate output based on changes to particular directory (I did that in [research](https://github.com/xvnpw/ai-nutrition-pro-design-gpt3.5)). 289 | 290 | User Stories feature requires two new parameters: 291 | - `input_architecture_files` - json array of paths of input architecture files e.g. `["arch-1.md","arch-2.md"]` 292 | - `input_architecture_threat_model_file` - path to architecture threat model e.g. `ARCHITECTURE_SECURITY.md` 293 | 294 | and one optional: 295 | - `user_story_output_suffix` - suffix that will be added to input file name to create output file, e.g. `_SECURITY` 296 | 297 | #### Trigger on changes to directory 298 | 299 | In case of user story, build is triggered on changes to particular directory. First, it needs to figure out which files were changed and process them individually. 300 | 301 | As you can see, we don't use `input_files` parameter. This time we watch the whole directory for changes: 302 | 303 | ```yaml 304 | on: 305 | push: 306 | branches: 307 | - main 308 | paths: 309 | - 'user-stories/*.md' 310 | - '!user-stories/*_SECURITY.md' 311 | ``` 312 | 313 | For your own directories, you need to adjust `paths` configuration. The same apply for committing changes with `add: 'user-stories/'`. 314 | 315 | **Example (direct push into repository):** 316 | 317 | ```yaml 318 | on: 319 | push: 320 | branches: 321 | - main 322 | paths: 323 | - 'user-stories/*.md' 324 | - '!user-stories/*_SECURITY.md' 325 | 326 | jobs: 327 | user_story_ai_tm_job: 328 | runs-on: ubuntu-latest 329 | 330 | permissions: 331 | # Give the default GITHUB_TOKEN write permission to commit and push the 332 | # added or changed files to the repository. 333 | contents: write 334 | 335 | name: Will run ai threat modeling action for user story analysis 336 | steps: 337 | - name: Checkout repo 338 | uses: actions/checkout@v3 339 | - name: Check which files were changed 340 | id: files_check 341 | uses: lots0logs/gh-action-get-changed-files@2.2.2 342 | with: 343 | token: ${{ secrets.GITHUB_TOKEN }} 344 | - name: Printing 345 | run: | 346 | echo "${{ steps.files_check.outputs.all }}" 347 | - name: Generate user story security acceptance criteria 348 | uses: xvnpw/ai-threat-modeling-action@v1.3.4 349 | with: 350 | type: 'user-story' 351 | input_files: "${{ steps.files_check.outputs.all }}" 352 | input_architecture_files: '["ARCHITECTURE.md"]' 353 | input_architecture_threat_model_file: "ARCHITECTURE_SECURITY.md" 354 | user_story_output_suffix: "_SECURITY" 355 | temperature: 0 356 | verbose: true 357 | model: "gpt-3.5-turbo-16k" 358 | env: 359 | OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} 360 | - name: Commit changes 361 | uses: EndBug/add-and-commit@v9 362 | with: 363 | message: 'User stories: security acceptance criteria' 364 | add: 'user-stories/' 365 | ``` 366 | 367 | #### Trigger on issue change 368 | 369 | In this case we consider only stories with certain label: 370 | 371 | ```yaml 372 | if: contains(github.event.issue.labels.*.name, 'ai-threat-modeling') 373 | ``` 374 | 375 | Comment is added (or updated) using [peter-evans/find-comment](https://github.com/peter-evans/find-comment) and [peter-evans/create-or-update-comment](https://github.com/peter-evans/create-or-update-comment) actions. 376 | 377 | **Example (comment on issue):** 378 | 379 | ```yaml 380 | name: Run ai threat modeling action for user story in issue analysis 381 | on: 382 | issues: 383 | types: 384 | - labeled 385 | - edited 386 | 387 | jobs: 388 | user_story_issue_ai_devsecops: 389 | name: Run ai threat modeling action for user story in issue analysis 390 | if: contains(github.event.issue.labels.*.name, 'ai-threat-modeling') 391 | runs-on: ubuntu-latest 392 | permissions: 393 | issues: write 394 | contents: write 395 | 396 | steps: 397 | - name: Checkout repo 398 | uses: actions/checkout@v3 399 | - uses: actions/github-script@v6 400 | id: set-result 401 | with: 402 | result-encoding: string 403 | retries: 3 404 | script: | 405 | const issue = await github.rest.issues.get({ 406 | issue_number: ${{ github.event.issue.number }}, 407 | owner: "${{ github.repository_owner }}", 408 | repo: "${{ github.event.repository.name }}", 409 | }); 410 | const body = issue.data.body; 411 | const fs = require('fs'); 412 | fs.writeFile('${{ github.workspace }}/issue_body.md', body, (err) => { 413 | if (err) throw err; 414 | console.log('Data written to file'); 415 | }); 416 | return JSON.stringify(body); 417 | - name: Generate user story security acceptance criteria 418 | uses: xvnpw/ai-threat-modeling-action@v1.3.4 419 | with: 420 | type: 'user-story' 421 | input_files: '["issue_body.md"]' 422 | input_architecture_files: '["ARCHITECTURE.md"]' 423 | input_architecture_threat_model_file: "ARCHITECTURE_SECURITY.md" 424 | temperature: 0 425 | verbose: true 426 | model: "gpt-3.5-turbo-16k" 427 | env: 428 | OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} 429 | - name: Find Comment 430 | uses: peter-evans/find-comment@v2 431 | id: fc 432 | with: 433 | issue-number: ${{ github.event.issue.number }} 434 | comment-author: 'github-actions[bot]' 435 | body-includes: (AI Generated) Security Related Acceptance Criteria 436 | - name: Add comment 437 | uses: peter-evans/create-or-update-comment@v3 438 | with: 439 | comment-id: ${{ steps.fc.outputs.comment-id }} 440 | issue-number: ${{ github.event.issue.number }} 441 | body-path: ${{ github.workspace }}/issue_body_SECURITY.md 442 | edit-mode: replace 443 | ``` 444 | 445 | ### Review of input file 446 | 447 | **Example (direct push into repository):** 448 | 449 | ```yaml 450 | on: 451 | push: 452 | branches: 453 | - main 454 | paths: 455 | - 'ARCHITECTURE.md' 456 | workflow_dispatch: 457 | 458 | jobs: 459 | architecture_ai_review_job: 460 | runs-on: ubuntu-latest 461 | 462 | permissions: 463 | # Give the default GITHUB_TOKEN write permission to commit and push the 464 | # added or changed files to the repository. 465 | contents: write 466 | 467 | name: Run ai threat modeling action for architecture review 468 | steps: 469 | - name: Checkout repo 470 | uses: actions/checkout@v3 471 | - name: Generate architecture review 472 | uses: xvnpw/ai-threat-modeling-action@v1.3.4 473 | with: 474 | type: 'architecture' # will create threat model 475 | input_files: 'ARCHITECTURE.md' 476 | output_file: 'ARCHITECTURE_REVIEW.md' 477 | review: true 478 | temperature: 0.2 479 | verbose: true 480 | model: 'gpt-4' 481 | env: 482 | OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} 483 | - name: Commit changes 484 | uses: EndBug/add-and-commit@v9 485 | with: 486 | message: 'Project architecture review' 487 | add: 'ARCHITECTURE_REVIEW.md' 488 | pull: '--rebase --autostash' 489 | ``` 490 | 491 | ### Push into Repository 492 | 493 | With [Add & Commit](https://github.com/marketplace/actions/add-commit) you can get `output_file` easily committed into repository: 494 | 495 | ```yaml 496 | - name: Commit changes 497 | uses: EndBug/add-and-commit@v9 498 | with: 499 | message: 'Project architecture threat model' 500 | add: 'ARCHITECTURE_SECURITY.md' 501 | ``` 502 | 503 | If you change output file, remember to change commit file: 504 | ```yaml 505 | - name: Commit changes 506 | uses: EndBug/add-and-commit@v9 507 | with: 508 | message: 'Project security requirements' 509 | add: 'project-sec-reqs.md' 510 | ``` 511 | 512 | ### Create Pull Request 513 | 514 | With [Create Pull Request](https://github.com/marketplace/actions/create-pull-request) you can create new pull request with `output_file`: 515 | 516 | ```yaml 517 | - name: Create Pull Request 518 | uses: peter-evans/create-pull-request@v5 519 | with: 520 | branch: create-pull-request/project 521 | title: (AI Generated) High Level Security and Privacy Requirements 522 | body: Automated pull request based on your changes to project. Please review it carefully. 523 | labels: 'security, ai' 524 | ``` 525 | 526 | In this mode, you also need to adjust permissions for workflow: 527 | 528 | ```yaml 529 | permissions: 530 | # Give the default GITHUB_TOKEN write permission to commit and push the 531 | # added or changed files to the repository. 532 | # It has also permission to pull requests 533 | contents: write 534 | pull-requests: write 535 | ``` 536 | 537 | Also [change settings](https://github.com/marketplace/actions/create-pull-request#workflow-permissions) for actions. 538 | 539 | ### Custom Prompts 540 | 541 | You might want to tune prompts. To do so, you don't need to fork action, but provide templates directory into your target repository: 542 | 543 | ```bash 544 | cd $HOME/ # your directory with repositories 545 | git clone git@github.com:xvnpw/ai-threat-modeling-action.git 546 | cp -r ai-threat-modeling-action/templates / 547 | cd /templates 548 | # edit templates 549 | ``` 550 | 551 | In workflow file add: 552 | 553 | ```yaml 554 | uses: xvnpw/ai-threat-modeling-action@v1.3.4 555 | with: 556 | ... 557 | templates_dir: './templates' 558 | ``` 559 | 560 | `./templates` - is directory relative to `` root. 561 | 562 | ## 🎉 Roadmap 563 | 564 | This project started as research of LLMs capabilities, but it improved over time beyond simple PoC. With version 1, it can be used to review documents in github using direct push, pr or issues. Further development or fixes are **not guaranteed**. If you plan to use it in your company, best to fork it and tune to your needs. 565 | 566 | ## 🚀 Tech Stack 567 | 568 | - Python 569 | - LLM Tooling: [Langchain](https://github.com/hwchase17/langchain) 570 | - LLM: [OpenAI GPT](https://openai.com/), [OpenRouter](https://openrouter.ai/) 571 | 572 | ## Fork 573 | 574 | Fork this project. Edit files and release action: 575 | 576 | ``` 577 | git add . 578 | git commit -m "My first action is ready" 579 | git tag -a -m "My first action release" v1 580 | git push --follow-tags 581 | ``` 582 | 583 | ## Privacy 584 | 585 | ### OpenAI 586 | 587 | This project uses OpenAI API. By default your data will not be used for learning, as per [API data usage policies](https://openai.com/policies/api-data-usage-policies): 588 | > OpenAI will not use data submitted by customers via our API to train or improve our models, unless you explicitly decide to share your data with us for this purpose. You can opt-in to share data. 589 | 590 | ### OpenRouter 591 | 592 | OpenRouter describe privacy and filtering in [settings](https://openrouter.ai/account) for each model. 593 | -------------------------------------------------------------------------------- /action.yml: -------------------------------------------------------------------------------- 1 | # action.yml 2 | name: 'AI Threat Modeling' 3 | description: 'AI featured threat modeling and security review action' 4 | author: 'xvnpw' 5 | branding: 6 | icon: 'book-open' 7 | color: 'green' 8 | inputs: 9 | type: 10 | description: 'type of feature' # one of: project, architecture, user-story 11 | required: true 12 | default: '' 13 | provider: 14 | description: 'provider name' # one of: openai, openrouter 15 | required: false 16 | default: 'openai' 17 | input_files: 18 | description: 'paths to input files formatted as json array' # e.g. ["user-stories/0001_STORE_DIET_INTRODUCTIONS.md","user-stories/0002_XYZ.md"] 19 | required: false 20 | default: '' 21 | output_file: 22 | description: 'path to output file' # e.g. architecture_threat_model.md 23 | required: false 24 | default: '' 25 | input_architecture_files: 26 | description: 'for user-story only: json array of paths of input architecture files' # e.g. ["arch-1.md","arch-2.md","arch_security.md"] 27 | required: false 28 | default: '' 29 | input_architecture_threat_model_file: 30 | description: 'for user-story only: path to architecture threat model' # e.g. ARCHITECTURE_SECURITY.md 31 | required: false 32 | default: '' 33 | model: 34 | description: 'type of LLM model' # e.g. gpt-3.5-turbo, anthropic/claude-2 35 | required: false 36 | default: 'gpt-4' 37 | temperature: 38 | description: 'sampling temperature for a model' 39 | required: false 40 | default: 0 41 | review: 42 | description: 'review input files using LLM' 43 | required: false 44 | default: false 45 | verbose: 46 | description: 'verbose messages' 47 | required: false 48 | default: false 49 | debug: 50 | description: 'debug messages' 51 | required: false 52 | default: false 53 | user_story_output_suffix: 54 | description: 'for user-story only: suffix that will be added to input file name to create output file' # e.g. _SECURITY 55 | required: false 56 | default: '_SECURITY' 57 | templates_dir: 58 | description: 'prompt templates directory' # e.g. './templates' 59 | required: false 60 | default: '/app/ai-threat-modeling/templates' # build-in templates from docker image 61 | runs: 62 | using: 'docker' 63 | image: 'Dockerfile' 64 | args: 65 | - ${{ inputs.type }} 66 | - ${{ inputs.input_files }} 67 | - ${{ inputs.output_file }} 68 | - ${{ inputs.input_architecture_files }} 69 | - ${{ inputs.input_architecture_threat_model_file }} 70 | - ${{ inputs.model }} 71 | - ${{ inputs.temperature }} 72 | - ${{ inputs.verbose }} 73 | - ${{ inputs.debug }} 74 | - ${{ inputs.user_story_output_suffix }} 75 | - ${{ inputs.templates_dir }} 76 | - ${{ inputs.provider }} 77 | - ${{ inputs.review }} 78 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # Docs 2 | 3 | - [Thread modelling using LLMs - CyberWiseCon Europe 2024](TM-using-LLMs.05.2024.pdf) 4 | -------------------------------------------------------------------------------- /docs/TM-using-LLMs.05.2024.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xvnpw/ai-threat-modeling-action/4bc1497cd1861d3e501c16239149012e4f02a960/docs/TM-using-LLMs.05.2024.pdf -------------------------------------------------------------------------------- /entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -l 2 | 3 | echo "[start] ai.tm.py..." 4 | 5 | ARGS="$1 --inputs $2 --output $3 -ai $4 -atmi $5 --model $6 --temperature $7 -usos ${10} -t ${11} --provider ${12}" 6 | 7 | if $8 = 'true'; then 8 | ARGS="$ARGS --verbose" 9 | fi 10 | 11 | if $9 = 'true'; then 12 | ARGS="$ARGS --debug" 13 | fi 14 | 15 | if ${13} = 'true'; then 16 | ARGS="$ARGS --review" 17 | fi 18 | 19 | echo $ARGS 20 | 21 | /usr/local/bin/python /app/ai-threat-modeling/ai-tm.py $ARGS 22 | -------------------------------------------------------------------------------- /scripts/bump-action-version.sh: -------------------------------------------------------------------------------- 1 | new_version=$1 2 | echo "setting version to ${new_version}..." 3 | sed -Ei "s|xvnpw/ai-threat-modeling-action@v[0-9]+\.[0-9]+\.[0-9]+|xvnpw/ai-threat-modeling-action@v${new_version}|g" ai-threat-modeling-action/README.md --------------------------------------------------------------------------------