aigis-cli 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- aigis_cli-1.0.0/LICENSE +21 -0
- aigis_cli-1.0.0/PKG-INFO +59 -0
- aigis_cli-1.0.0/README.md +32 -0
- aigis_cli-1.0.0/aigis_cli/SKILL.md +74 -0
- aigis_cli-1.0.0/aigis_cli/__init__.py +3 -0
- aigis_cli-1.0.0/aigis_cli/annotate.py +45 -0
- aigis_cli-1.0.0/aigis_cli/classify.py +192 -0
- aigis_cli-1.0.0/aigis_cli/cli.py +280 -0
- aigis_cli-1.0.0/aigis_cli/content/implement/audit-logging.md +171 -0
- aigis_cli-1.0.0/aigis_cli/content/implement/bias-monitoring.md +172 -0
- aigis_cli-1.0.0/aigis_cli/content/implement/confidence-scoring.md +180 -0
- aigis_cli-1.0.0/aigis_cli/content/implement/data-integrity.md +257 -0
- aigis_cli-1.0.0/aigis_cli/content/implement/explainability.md +174 -0
- aigis_cli-1.0.0/aigis_cli/content/implement/fallback-patterns.md +190 -0
- aigis_cli-1.0.0/aigis_cli/content/implement/human-oversight.md +220 -0
- aigis_cli-1.0.0/aigis_cli/content/implement/input-validation.md +212 -0
- aigis_cli-1.0.0/aigis_cli/content/implement/monitoring.md +207 -0
- aigis_cli-1.0.0/aigis_cli/content/implement/output-sanitization.md +183 -0
- aigis_cli-1.0.0/aigis_cli/content/implement/pii-handling.md +207 -0
- aigis_cli-1.0.0/aigis_cli/content/implement/prompt-security.md +153 -0
- aigis_cli-1.0.0/aigis_cli/content/implement/rag-security.md +230 -0
- aigis_cli-1.0.0/aigis_cli/content/implement/rate-limiting.md +217 -0
- aigis_cli-1.0.0/aigis_cli/content/implement/supply-chain.md +193 -0
- aigis_cli-1.0.0/aigis_cli/content/index/audit-scan.md +403 -0
- aigis_cli-1.0.0/aigis_cli/content/index/frameworks.md +82 -0
- aigis_cli-1.0.0/aigis_cli/content/index/guardrails.json +23 -0
- aigis_cli-1.0.0/aigis_cli/content/index/taxonomy.md +81 -0
- aigis_cli-1.0.0/aigis_cli/content/templates/ai-impact-assessment.md +54 -0
- aigis_cli-1.0.0/aigis_cli/content/templates/intended-purpose-doc.md +39 -0
- aigis_cli-1.0.0/aigis_cli/content/templates/risk-characterization.md +34 -0
- aigis_cli-1.0.0/aigis_cli/content/templates/third-party-assessment.md +41 -0
- aigis_cli-1.0.0/aigis_cli/content/verify/checklist-audit-logging.md +13 -0
- aigis_cli-1.0.0/aigis_cli/content/verify/checklist-bias-monitoring.md +13 -0
- aigis_cli-1.0.0/aigis_cli/content/verify/checklist-confidence-scoring.md +13 -0
- aigis_cli-1.0.0/aigis_cli/content/verify/checklist-data-integrity.md +12 -0
- aigis_cli-1.0.0/aigis_cli/content/verify/checklist-explainability.md +13 -0
- aigis_cli-1.0.0/aigis_cli/content/verify/checklist-fallback-patterns.md +13 -0
- aigis_cli-1.0.0/aigis_cli/content/verify/checklist-human-oversight.md +14 -0
- aigis_cli-1.0.0/aigis_cli/content/verify/checklist-input-validation.md +16 -0
- aigis_cli-1.0.0/aigis_cli/content/verify/checklist-monitoring.md +13 -0
- aigis_cli-1.0.0/aigis_cli/content/verify/checklist-output-sanitization.md +14 -0
- aigis_cli-1.0.0/aigis_cli/content/verify/checklist-pii-handling.md +14 -0
- aigis_cli-1.0.0/aigis_cli/content/verify/checklist-prompt-security.md +13 -0
- aigis_cli-1.0.0/aigis_cli/content/verify/checklist-rag-security.md +12 -0
- aigis_cli-1.0.0/aigis_cli/content/verify/checklist-rate-limiting.md +13 -0
- aigis_cli-1.0.0/aigis_cli/content/verify/checklist-supply-chain.md +13 -0
- aigis_cli-1.0.0/aigis_cli/fetch.py +99 -0
- aigis_cli-1.0.0/aigis_cli/init_ide.py +107 -0
- aigis_cli-1.0.0/aigis_cli/keywords.py +136 -0
- aigis_cli-1.0.0/aigis_cli/search.py +69 -0
- aigis_cli-1.0.0/aigis_cli.egg-info/PKG-INFO +59 -0
- aigis_cli-1.0.0/aigis_cli.egg-info/SOURCES.txt +56 -0
- aigis_cli-1.0.0/aigis_cli.egg-info/dependency_links.txt +1 -0
- aigis_cli-1.0.0/aigis_cli.egg-info/entry_points.txt +2 -0
- aigis_cli-1.0.0/aigis_cli.egg-info/requires.txt +6 -0
- aigis_cli-1.0.0/aigis_cli.egg-info/top_level.txt +1 -0
- aigis_cli-1.0.0/pyproject.toml +49 -0
- aigis_cli-1.0.0/setup.cfg +4 -0
aigis_cli-1.0.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Nayan Kanaparthi
|
|
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.
|
aigis_cli-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: aigis-cli
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: AI governance guardrails for coding agents. Framework-aligned security and compliance patterns from NIST AI RMF, OWASP Top 10 for LLMs, and ISO/IEC 42001.
|
|
5
|
+
License-Expression: MIT
|
|
6
|
+
Project-URL: Homepage, https://github.com/NayanKanaparthi/aigis
|
|
7
|
+
Project-URL: Repository, https://github.com/NayanKanaparthi/aigis
|
|
8
|
+
Keywords: ai,governance,security,compliance,llm,owasp,nist,iso42001,guardrails,coding-agent
|
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Topic :: Security
|
|
17
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
|
18
|
+
Requires-Python: >=3.9
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
License-File: LICENSE
|
|
21
|
+
Requires-Dist: click>=8.0
|
|
22
|
+
Requires-Dist: rich>=13.0
|
|
23
|
+
Requires-Dist: python-frontmatter>=1.0
|
|
24
|
+
Provides-Extra: dev
|
|
25
|
+
Requires-Dist: build>=1.0; extra == "dev"
|
|
26
|
+
Dynamic: license-file
|
|
27
|
+
|
|
28
|
+
# aigis-cli (Python)
|
|
29
|
+
|
|
30
|
+
AI governance guardrails for coding agents. Python port of the [@aigis-ai/cli](https://www.npmjs.com/package/@aigis-ai/cli) npm package.
|
|
31
|
+
|
|
32
|
+
Curated, agent-consumable security and compliance patterns from NIST AI RMF, OWASP Top 10 for LLMs, and ISO/IEC 42001.
|
|
33
|
+
|
|
34
|
+
## Install
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
pip install aigis-cli
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Quick start
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
aigis classify --traits uses-llm,processes-pii,accepts-user-input
|
|
44
|
+
aigis get input-validation pii-handling
|
|
45
|
+
aigis verify input-validation pii-handling
|
|
46
|
+
aigis template ai-impact-assessment
|
|
47
|
+
aigis audit --scan
|
|
48
|
+
aigis search pii
|
|
49
|
+
aigis traits
|
|
50
|
+
aigis init cursor
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Documentation
|
|
54
|
+
|
|
55
|
+
See the full documentation at [github.com/NayanKanaparthi/aigis](https://github.com/NayanKanaparthi/aigis).
|
|
56
|
+
|
|
57
|
+
## License
|
|
58
|
+
|
|
59
|
+
[MIT](LICENSE)
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# aigis-cli (Python)
|
|
2
|
+
|
|
3
|
+
AI governance guardrails for coding agents. Python port of the [@aigis-ai/cli](https://www.npmjs.com/package/@aigis-ai/cli) npm package.
|
|
4
|
+
|
|
5
|
+
Curated, agent-consumable security and compliance patterns from NIST AI RMF, OWASP Top 10 for LLMs, and ISO/IEC 42001.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pip install aigis-cli
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quick start
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
aigis classify --traits uses-llm,processes-pii,accepts-user-input
|
|
17
|
+
aigis get input-validation pii-handling
|
|
18
|
+
aigis verify input-validation pii-handling
|
|
19
|
+
aigis template ai-impact-assessment
|
|
20
|
+
aigis audit --scan
|
|
21
|
+
aigis search pii
|
|
22
|
+
aigis traits
|
|
23
|
+
aigis init cursor
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Documentation
|
|
27
|
+
|
|
28
|
+
See the full documentation at [github.com/NayanKanaparthi/aigis](https://github.com/NayanKanaparthi/aigis).
|
|
29
|
+
|
|
30
|
+
## License
|
|
31
|
+
|
|
32
|
+
[MIT](LICENSE)
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: aigis
|
|
3
|
+
description: AI governance skill for coding agents. Provides framework-aligned security and compliance patterns from NIST AI RMF, OWASP Top 10 for LLMs, and ISO/IEC 42001. Use before building any AI/LLM feature or when auditing existing AI systems.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Aigis — AI Governance Skill
|
|
7
|
+
|
|
8
|
+
Use the aigis CLI for governance patterns when building or auditing AI/LLM features.
|
|
9
|
+
|
|
10
|
+
## Quick start — new feature
|
|
11
|
+
\`\`\`bash
|
|
12
|
+
# 1. Classify your system to get relevant controls
|
|
13
|
+
aigis classify --traits uses-llm,accepts-user-input,processes-pii,is-external --json
|
|
14
|
+
|
|
15
|
+
# 2. Fetch implementation patterns for each recommended file
|
|
16
|
+
aigis get input-validation pii-handling prompt-security audit-logging
|
|
17
|
+
|
|
18
|
+
# 3. Write code applying the patterns from the fetched files
|
|
19
|
+
|
|
20
|
+
# 4. After writing code, run verification
|
|
21
|
+
aigis verify input-validation pii-handling prompt-security audit-logging
|
|
22
|
+
|
|
23
|
+
# 5. If risk tier is HIGH or MEDIUM, generate compliance docs
|
|
24
|
+
aigis template ai-impact-assessment intended-purpose-doc
|
|
25
|
+
\`\`\`
|
|
26
|
+
|
|
27
|
+
## Quick start — audit existing project
|
|
28
|
+
\`\`\`bash
|
|
29
|
+
# 1. Get the structured audit scan prompt
|
|
30
|
+
aigis audit --scan
|
|
31
|
+
|
|
32
|
+
# 2. Follow the scan instructions: inventory the project, detect traits, classify
|
|
33
|
+
|
|
34
|
+
# 3. Run the full audit with detected traits
|
|
35
|
+
aigis audit --traits uses-llm,processes-pii,is-external
|
|
36
|
+
|
|
37
|
+
# 4. Evaluate existing code against each check, produce gap report
|
|
38
|
+
\`\`\`
|
|
39
|
+
|
|
40
|
+
## When to use
|
|
41
|
+
- Before writing any LLM API call or AI feature (new code)
|
|
42
|
+
- When auditing an existing AI system for governance gaps (existing code)
|
|
43
|
+
- Before processing any sensitive data through an AI system
|
|
44
|
+
- Before deploying any AI feature to production
|
|
45
|
+
- When onboarding to a new AI project to understand what controls exist
|
|
46
|
+
|
|
47
|
+
## Commands
|
|
48
|
+
- \`aigis classify --traits <comma-separated>\` — get risk tier and relevant files
|
|
49
|
+
- \`aigis classify "<description>"\` — same, using natural language (keyword matching)
|
|
50
|
+
- \`aigis get <file-id> [file-id...]\` — fetch implementation patterns (one or more)
|
|
51
|
+
- \`aigis get <file-id> --lang py|js\` — fetch filtered to one language
|
|
52
|
+
- \`aigis verify <file-id> [file-id...]\` — fetch verification checklists
|
|
53
|
+
- \`aigis template <template-id> [template-id...]\` — fetch compliance documentation templates
|
|
54
|
+
- \`aigis audit --scan\` — get structured audit prompt for scanning existing codebases
|
|
55
|
+
- \`aigis audit --traits <comma-separated>\` — get bundled classification + all checklists for audit
|
|
56
|
+
- \`aigis search <query>\` — search across all content by keyword or control ID
|
|
57
|
+
- \`aigis search --list\` — list all available files
|
|
58
|
+
- \`aigis annotate <file-id> "<note>"\` — attach a local note for future sessions
|
|
59
|
+
- \`aigis annotate --list\` — list all annotations
|
|
60
|
+
- \`aigis init cursor|claude-code|windsurf|copilot\` — set up aigis for your IDE
|
|
61
|
+
|
|
62
|
+
## Available traits (22)
|
|
63
|
+
AI architecture: uses-llm, uses-rag, uses-finetuned, uses-thirdparty-api, is-agentic, is-multimodal
|
|
64
|
+
Data sensitivity: processes-pii, handles-financial, handles-health, handles-proprietary, handles-minors
|
|
65
|
+
Impact scope: influences-decisions, accepts-user-input, is-external, is-internal, is-high-volume
|
|
66
|
+
Output type: generates-code, generates-content, multi-model-pipeline
|
|
67
|
+
Jurisdiction: jurisdiction-eu, jurisdiction-us-regulated, jurisdiction-global
|
|
68
|
+
|
|
69
|
+
## Integration
|
|
70
|
+
- Claude Code: place this file in ~/.claude/skills/aigis/SKILL.md
|
|
71
|
+
- Cursor: run \`aigis init cursor\` in your project root
|
|
72
|
+
- Windsurf: run \`aigis init windsurf\` in your project root
|
|
73
|
+
- GitHub Copilot: run \`aigis init copilot\` in your project root
|
|
74
|
+
- Any agent: include aigis usage instructions in system prompt
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
from datetime import date
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
AIGIS_DIR = Path.home() / ".aigis"
|
|
8
|
+
ANNOTATIONS_FILE = AIGIS_DIR / "annotations.json"
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def _load_annotations() -> dict:
|
|
12
|
+
if not ANNOTATIONS_FILE.exists():
|
|
13
|
+
return {}
|
|
14
|
+
try:
|
|
15
|
+
return json.loads(ANNOTATIONS_FILE.read_text(encoding="utf-8"))
|
|
16
|
+
except (json.JSONDecodeError, OSError):
|
|
17
|
+
return {}
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def _save_annotations(data: dict) -> None:
|
|
21
|
+
AIGIS_DIR.mkdir(parents=True, exist_ok=True)
|
|
22
|
+
ANNOTATIONS_FILE.write_text(json.dumps(data, indent=2), encoding="utf-8")
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def annotate(file_id: str, note: str) -> None:
|
|
26
|
+
data = _load_annotations()
|
|
27
|
+
data.setdefault(file_id, []).append({
|
|
28
|
+
"note": note,
|
|
29
|
+
"date": date.today().isoformat(),
|
|
30
|
+
})
|
|
31
|
+
_save_annotations(data)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def get_annotations(file_id: str) -> list[dict]:
|
|
35
|
+
return _load_annotations().get(file_id, [])
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def list_annotations() -> dict:
|
|
39
|
+
return _load_annotations()
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def clear_annotation(file_id: str) -> None:
|
|
43
|
+
data = _load_annotations()
|
|
44
|
+
data.pop(file_id, None)
|
|
45
|
+
_save_annotations(data)
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
ALL_TRAITS = [
|
|
4
|
+
"uses-llm", "uses-rag", "uses-finetuned", "uses-thirdparty-api", "is-agentic", "is-multimodal",
|
|
5
|
+
"processes-pii", "handles-financial", "handles-health", "handles-proprietary", "handles-minors",
|
|
6
|
+
"influences-decisions", "accepts-user-input", "is-external", "is-internal", "is-high-volume",
|
|
7
|
+
"generates-code", "generates-content", "multi-model-pipeline",
|
|
8
|
+
"jurisdiction-eu", "jurisdiction-us-regulated", "jurisdiction-global",
|
|
9
|
+
]
|
|
10
|
+
|
|
11
|
+
TRAIT_FILES: dict[str, list[str]] = {
|
|
12
|
+
"uses-llm": ["input-validation", "output-sanitization", "prompt-security", "audit-logging", "monitoring"],
|
|
13
|
+
"uses-rag": ["rag-security", "data-integrity"],
|
|
14
|
+
"uses-finetuned": ["data-integrity", "supply-chain"],
|
|
15
|
+
"uses-thirdparty-api": ["supply-chain"],
|
|
16
|
+
"is-agentic": ["human-oversight", "rate-limiting", "fallback-patterns", "audit-logging"],
|
|
17
|
+
"is-multimodal": ["input-validation", "output-sanitization", "pii-handling"],
|
|
18
|
+
"processes-pii": ["pii-handling", "audit-logging"],
|
|
19
|
+
"handles-financial": ["pii-handling", "audit-logging", "bias-monitoring"],
|
|
20
|
+
"handles-health": ["pii-handling", "audit-logging", "bias-monitoring", "explainability"],
|
|
21
|
+
"handles-proprietary": ["pii-handling", "prompt-security"],
|
|
22
|
+
"handles-minors": ["pii-handling", "bias-monitoring", "human-oversight"],
|
|
23
|
+
"influences-decisions": ["bias-monitoring", "confidence-scoring", "human-oversight", "explainability"],
|
|
24
|
+
"accepts-user-input": ["input-validation", "output-sanitization"],
|
|
25
|
+
"is-external": ["rate-limiting", "confidence-scoring"],
|
|
26
|
+
"is-internal": [],
|
|
27
|
+
"is-high-volume": ["rate-limiting", "monitoring", "fallback-patterns"],
|
|
28
|
+
"generates-code": ["output-sanitization", "human-oversight", "fallback-patterns"],
|
|
29
|
+
"generates-content": ["confidence-scoring", "bias-monitoring", "audit-logging"],
|
|
30
|
+
"multi-model-pipeline": ["audit-logging", "monitoring", "fallback-patterns", "data-integrity"],
|
|
31
|
+
"jurisdiction-eu": [],
|
|
32
|
+
"jurisdiction-us-regulated": [],
|
|
33
|
+
"jurisdiction-global": [],
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
FILE_CONTROLS: dict[str, dict[str, list[str]]] = {
|
|
37
|
+
"input-validation": {"owasp": ["LLM01"], "nist": ["MEASURE-2.7", "MANAGE-1.3"], "iso": ["Clause-8.2", "Annex-A.6"]},
|
|
38
|
+
"output-sanitization": {"owasp": ["LLM05"], "nist": ["MEASURE-2.6", "MEASURE-2.7"], "iso": ["Clause-8.2"]},
|
|
39
|
+
"pii-handling": {"owasp": ["LLM02"], "nist": ["MAP-2.1", "MEASURE-2.10"], "iso": ["Annex-A.7", "Annex-A.4"]},
|
|
40
|
+
"prompt-security": {"owasp": ["LLM07"], "nist": ["MEASURE-2.7", "MEASURE-2.8"], "iso": ["Clause-8.2"]},
|
|
41
|
+
"human-oversight": {"owasp": ["LLM06"], "nist": ["MAP-3.5", "MANAGE-1.3", "MANAGE-4.1"], "iso": ["Annex-A.9", "Clause-8.4"]},
|
|
42
|
+
"supply-chain": {"owasp": ["LLM03"], "nist": ["GOVERN-6.1", "GOVERN-6.2", "MANAGE-3.1", "MANAGE-3.2"], "iso": ["Annex-A.10"]},
|
|
43
|
+
"data-integrity": {"owasp": ["LLM04"], "nist": ["MAP-2.3", "MEASURE-2.6"], "iso": ["Annex-A.7"]},
|
|
44
|
+
"rag-security": {"owasp": ["LLM08"], "nist": ["MEASURE-2.7"], "iso": ["Clause-8.2", "Annex-A.7"]},
|
|
45
|
+
"confidence-scoring": {"owasp": ["LLM09"], "nist": ["MAP-2.2", "MEASURE-2.5", "MEASURE-2.9"], "iso": ["Annex-A.8"]},
|
|
46
|
+
"rate-limiting": {"owasp": ["LLM10"], "nist": ["MEASURE-2.6", "MANAGE-2.4"], "iso": ["Clause-8.2"]},
|
|
47
|
+
"audit-logging": {"owasp": [], "nist": ["MEASURE-2.8", "MANAGE-4.1", "MANAGE-4.3"], "iso": ["Clause-9.1", "Annex-A.6"]},
|
|
48
|
+
"bias-monitoring": {"owasp": [], "nist": ["MAP-2.3", "MEASURE-2.11", "MEASURE-3.1"], "iso": ["Clause-6.1", "Annex-C"]},
|
|
49
|
+
"fallback-patterns": {"owasp": [], "nist": ["MEASURE-2.6", "MANAGE-2.3", "MANAGE-2.4"], "iso": ["Clause-8.2"]},
|
|
50
|
+
"monitoring": {"owasp": [], "nist": ["MEASURE-2.4", "MEASURE-3.1", "MANAGE-4.1", "MANAGE-4.2"], "iso": ["Clause-9.1", "Clause-10"]},
|
|
51
|
+
"explainability": {"owasp": [], "nist": ["MEASURE-2.8", "MEASURE-2.9"], "iso": ["Annex-A.8", "Clause-7.4"]},
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def classify(trait_list: list[str]) -> dict:
|
|
56
|
+
ts = set(trait_list)
|
|
57
|
+
warnings: list[str] = []
|
|
58
|
+
|
|
59
|
+
invalid = [t for t in trait_list if t not in ALL_TRAITS]
|
|
60
|
+
if invalid:
|
|
61
|
+
raise ValueError(
|
|
62
|
+
f'Unknown traits: {", ".join(invalid)}. Run "aigis traits" to see available traits.'
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
# Constraint C1: is-internal + is-external
|
|
66
|
+
if "is-internal" in ts and "is-external" in ts:
|
|
67
|
+
warnings.append("Both is-internal and is-external selected. Treating as is-external (stricter).")
|
|
68
|
+
ts.discard("is-internal")
|
|
69
|
+
|
|
70
|
+
# Step 1: trait-based file selection
|
|
71
|
+
files: set[str] = set()
|
|
72
|
+
for t in ts:
|
|
73
|
+
for f in TRAIT_FILES.get(t, []):
|
|
74
|
+
files.add(f)
|
|
75
|
+
|
|
76
|
+
# Step 2: risk tier
|
|
77
|
+
sens_data = bool(
|
|
78
|
+
ts & {"processes-pii", "handles-financial", "handles-health", "handles-proprietary", "handles-minors"}
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
tier = "LOW"
|
|
82
|
+
reason = "no high/medium triggers"
|
|
83
|
+
|
|
84
|
+
if "influences-decisions" in ts:
|
|
85
|
+
tier, reason = "HIGH", "influences-decisions"
|
|
86
|
+
elif "handles-health" in ts:
|
|
87
|
+
tier, reason = "HIGH", "handles-health"
|
|
88
|
+
elif "handles-financial" in ts and "accepts-user-input" in ts:
|
|
89
|
+
tier, reason = "HIGH", "handles-financial + accepts-user-input"
|
|
90
|
+
elif "handles-minors" in ts:
|
|
91
|
+
tier, reason = "HIGH", "handles-minors"
|
|
92
|
+
elif ("jurisdiction-eu" in ts or "jurisdiction-global" in ts) and sens_data:
|
|
93
|
+
tier, reason = "HIGH", "jurisdiction-eu + sensitive data"
|
|
94
|
+
elif "generates-code" in ts and "is-external" in ts:
|
|
95
|
+
tier, reason = "HIGH", "generates-code + is-external"
|
|
96
|
+
elif "generates-code" in ts and "is-agentic" in ts:
|
|
97
|
+
tier, reason = "HIGH", "generates-code + is-agentic"
|
|
98
|
+
elif "processes-pii" in ts:
|
|
99
|
+
tier, reason = "MEDIUM", "processes-pii"
|
|
100
|
+
elif "is-external" in ts:
|
|
101
|
+
tier, reason = "MEDIUM", "is-external"
|
|
102
|
+
elif "is-agentic" in ts:
|
|
103
|
+
tier, reason = "MEDIUM", "is-agentic"
|
|
104
|
+
elif "handles-proprietary" in ts:
|
|
105
|
+
tier, reason = "MEDIUM", "handles-proprietary"
|
|
106
|
+
elif "generates-content" in ts:
|
|
107
|
+
tier, reason = "MEDIUM", "generates-content"
|
|
108
|
+
elif "multi-model-pipeline" in ts:
|
|
109
|
+
tier, reason = "MEDIUM", "multi-model-pipeline"
|
|
110
|
+
elif "jurisdiction-us-regulated" in ts:
|
|
111
|
+
tier, reason = "MEDIUM", "jurisdiction-us-regulated"
|
|
112
|
+
elif "generates-code" in ts:
|
|
113
|
+
tier, reason = "MEDIUM", "generates-code"
|
|
114
|
+
|
|
115
|
+
# Jurisdiction modifier
|
|
116
|
+
if ("jurisdiction-eu" in ts or "jurisdiction-global" in ts) and tier != "HIGH":
|
|
117
|
+
old_tier = tier
|
|
118
|
+
tier = "MEDIUM" if tier == "LOW" else "HIGH"
|
|
119
|
+
reason += f" (elevated from {old_tier} by EU/global jurisdiction)"
|
|
120
|
+
|
|
121
|
+
# Step 3: guardrails
|
|
122
|
+
guardrails_fired: list[dict] = []
|
|
123
|
+
|
|
124
|
+
# G12 removal guardrail fires first
|
|
125
|
+
if "uses-llm" in ts and "uses-thirdparty-api" not in ts and "supply-chain" in files:
|
|
126
|
+
files.discard("supply-chain")
|
|
127
|
+
guardrails_fired.append({
|
|
128
|
+
"id": "G12",
|
|
129
|
+
"action": "REMOVE supply-chain",
|
|
130
|
+
"rationale": "Self-hosted models skip third-party controls",
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
guardrails = [
|
|
134
|
+
("G1", lambda: sens_data and "audit-logging" not in files, "audit-logging", "Sensitive data requires traceability"),
|
|
135
|
+
("G2", lambda: "handles-health" in ts and "bias-monitoring" not in files, "bias-monitoring", "Health data has demographic bias risks"),
|
|
136
|
+
("G3", lambda: "handles-financial" in ts and "influences-decisions" in ts and "fallback-patterns" not in files, "fallback-patterns", "Financial decisions need safe failure"),
|
|
137
|
+
("G4", lambda: "is-agentic" in ts and "human-oversight" not in files, "human-oversight", "Autonomous systems need oversight"),
|
|
138
|
+
("G5", lambda: "generates-code" in ts and "output-sanitization" not in files, "output-sanitization", "Generated code is execution risk"),
|
|
139
|
+
("G6", lambda: "jurisdiction-eu" in ts and "explainability" not in files, "explainability", "EU AI Act requires explainability"),
|
|
140
|
+
("G7", lambda: "jurisdiction-eu" in ts and "bias-monitoring" not in files, "bias-monitoring", "EU AI Act mandates non-discrimination"),
|
|
141
|
+
("G8", lambda: "handles-minors" in ts and "human-oversight" not in files, "human-oversight", "Systems affecting children require review"),
|
|
142
|
+
("G9", lambda: "multi-model-pipeline" in ts and "monitoring" not in files, "monitoring", "Multi-model compounding failures"),
|
|
143
|
+
("G10", lambda: tier == "HIGH" and "monitoring" not in files, "monitoring", "High-risk systems need monitoring"),
|
|
144
|
+
("G11", lambda: tier == "HIGH" and "fallback-patterns" not in files, "fallback-patterns", "High-risk systems must fail safely"),
|
|
145
|
+
("G13", lambda: "jurisdiction-us-regulated" in ts and "audit-logging" not in files, "audit-logging", "US regulated industries need audit trails"),
|
|
146
|
+
("G14", lambda: "jurisdiction-us-regulated" in ts and "human-oversight" not in files, "human-oversight", "US regulated industries need human review"),
|
|
147
|
+
("G15", lambda: "generates-code" in ts and "human-oversight" not in files, "human-oversight", "Code generation needs human review"),
|
|
148
|
+
]
|
|
149
|
+
|
|
150
|
+
for gid, cond, file, rationale in guardrails:
|
|
151
|
+
if cond():
|
|
152
|
+
files.add(file)
|
|
153
|
+
guardrails_fired.append({"id": gid, "action": f"ADD {file}", "rationale": rationale})
|
|
154
|
+
|
|
155
|
+
# Step 4: templates
|
|
156
|
+
templates: list[str] = []
|
|
157
|
+
if tier == "HIGH" or "jurisdiction-eu" in ts or "jurisdiction-global" in ts or "influences-decisions" in ts:
|
|
158
|
+
templates.extend(["ai-impact-assessment", "intended-purpose-doc", "risk-characterization"])
|
|
159
|
+
elif tier == "MEDIUM" or "jurisdiction-us-regulated" in ts:
|
|
160
|
+
templates.append("intended-purpose-doc")
|
|
161
|
+
|
|
162
|
+
if "uses-thirdparty-api" in ts and tier != "LOW":
|
|
163
|
+
templates.append("third-party-assessment")
|
|
164
|
+
|
|
165
|
+
if "jurisdiction-us-regulated" in ts and "ai-impact-assessment" not in templates:
|
|
166
|
+
templates.insert(0, "ai-impact-assessment")
|
|
167
|
+
|
|
168
|
+
# Step 5: collect control IDs
|
|
169
|
+
all_owasp: set[str] = set()
|
|
170
|
+
all_nist: set[str] = set()
|
|
171
|
+
all_iso: set[str] = set()
|
|
172
|
+
for f in files:
|
|
173
|
+
c = FILE_CONTROLS.get(f)
|
|
174
|
+
if c:
|
|
175
|
+
all_owasp.update(c["owasp"])
|
|
176
|
+
all_nist.update(c["nist"])
|
|
177
|
+
all_iso.update(c["iso"])
|
|
178
|
+
|
|
179
|
+
return {
|
|
180
|
+
"risk_tier": tier,
|
|
181
|
+
"reason": reason,
|
|
182
|
+
"traits": list(ts),
|
|
183
|
+
"implement_files": sorted(files),
|
|
184
|
+
"templates": list(dict.fromkeys(templates)),
|
|
185
|
+
"guardrails_fired": guardrails_fired,
|
|
186
|
+
"warnings": warnings,
|
|
187
|
+
"controls": {
|
|
188
|
+
"owasp": sorted(all_owasp),
|
|
189
|
+
"nist": sorted(all_nist),
|
|
190
|
+
"iso": sorted(all_iso),
|
|
191
|
+
},
|
|
192
|
+
}
|