Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
0dccb10
feat: add guidelines-security-analysis skill (architecture, questionn…
Aug 19, 2026
c78f559
fix: modify enforcement.md file to include guidances rom OWASP
Aug 19, 2026
798e3b0
fix: add a clause upfront on whether to run Gated (pause for confirma…
Aug 19, 2026
25d53d2
fix: In Step C list OWASP threat catalog as required input to produce…
Aug 19, 2026
dab8e3b
fix: compare the guidance file in Step D and add the ones that are no…
Aug 19, 2026
42c2047
fix: dedupes it against the OWASP-derived rules and check the combin…
Aug 20, 2026
ec241d9
modify the handoff point as guidelines
Aug 20, 2026
6531db6
add continuation to policy creation with updated guidelines
Aug 21, 2026
b51b30e
refacttor: rename folder from owasp to steps
Aug 21, 2026
702db01
add instructions to call security guided analysis to SKILL.md
Aug 21, 2026
0f3f84c
add instructions to call security guided analysis to README.md
Aug 21, 2026
c42b707
modify project structure to add guidance-security-analysis
Aug 21, 2026
3a65f3d
fix: reorder policy creation and security guided analysis
Aug 21, 2026
bc9138d
update README.md files for the examples to aid in running the securit…
Aug 21, 2026
3897d9f
update the security guidance analysis
Aug 21, 2026
640bb95
fix updated threats
Aug 21, 2026
a4dc5c7
Merge remote-tracking branch 'local/feat/guidelines-security-analysis…
Aug 21, 2026
be9c604
fix: remove tag with sources
Aug 25, 2026
1e79543
fix: update the target agent file path
Aug 25, 2026
29a6ea5
fix: remove redundant rules in both guidances
Aug 25, 2026
0fcb9b7
updated guidance for RagChabot
Aug 26, 2026
8fe20a4
remove recommendations
Aug 26, 2026
550ba3f
update security guidances for hr agent
Aug 26, 2026
3a04f55
update security guidances for hr agent
Aug 26, 2026
647973b
update security guidances for hr agent
Aug 26, 2026
ecfed72
update secuirity guidances for employee
Aug 26, 2026
3c2e3d8
updated guidances for call for papers
Aug 26, 2026
59e72dc
update security guidances for car-for-mcp
Aug 26, 2026
9302eef
revert to previous guidance for call for papers
Aug 26, 2026
7bf4d8a
fix: fix guidance-security-analysis: use input.args, append (don't ov…
Aug 26, 2026
f2fd7e9
fix: guidance-security-analysis docs: propagate append semantics to S…
Aug 26, 2026
4cd489e
update the security analysis for car-price-mcp
Sep 2, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 17 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ policy-bypass cases that target divergences between the guidance and the current
- **Refine** policies automatically through iterative feedback loops (patches for failed test cases, linting, etc.).

```
Guidance Description (NLP) + Agent Description → Enforceable Policy Creation → Test Generation → Policy Testing ⇄ Policy Refinement
Guidance (NLP) + Agent Description
→ [optional] Security-Grounded Guidance Analysis (A → B → C → D → E)
→ Enforceable Policy Creation → Test Generation → Policy Testing ⇄ Policy Refinement
```

## What Smith Needs from You
Expand Down Expand Up @@ -174,7 +176,7 @@ Smith operates as an agent skill with a CLI backend. The AI agent reads instruct
│ │ │
│ ┌────────────────────────┼───────────────────┬─────────┐ │
│ ▼ ▼ ▼ ▼ │
│ Policy Test Case Generatio Policy Policy │
│ Policy Test Case Generation Policy Policy │
│ Creation │ Testing Refinement │
│ │ ┌──────────┬────┼─────┬────────┐ │ │ │
│ ▼ ▼ ▼ ▼ ▼ └────⇄────┘ │
Expand Down Expand Up @@ -205,6 +207,18 @@ Create OPA policies from natural language specifications. The agent follows `opa

The policy only references data available from tool arguments and system variables. If a guidance rule requires context not available in either, it is logged as a suggestion rather than added to the policy.

### Create an OPA Policy with a Security-Grounded Guidance Analysis

A separate, standalone workflow that first grounds the guidance in an OWASP-mapped threat model, then (on explicit human trigger) runs Policy Creation above against the updated guidance. Use it when you want an OWASP review of the guidance itself before any Rego is written; otherwise Policy Creation above stands alone. The agent follows `opa_policy/guidelines-security-analysis/guidelines-security-analysis.md`, which runs in this order:

1. **Step A — Architecture Analysis** → `architecture.md`. Reads the MCP server's source and produces a layer-by-layer breakdown (HTTP API / Agent / MCP Tool / Tool Implementation / External Service) with trust boundaries, data flow, and available enforcement points.
2. **Step B — Policy Guidance Questionnaire** → `policy_guidance_questionnaire.md`. Turns `guidance.txt` plus the architecture into a structured Q&A covering roles, hard limits, rate limits, and response filtering, with confidence tags on every answer.
3. **Step C — Threat Model** → `threat_model.md`. Evaluates all 10 OWASP Top 10 for Agentic AI Security categories (ASI01–ASI10) against the architecture and questionnaire, producing concrete threat instances with source citations back into `architecture.md`.
4. **Step D — Enforcement Mapping** → `owasp_policy_guidelines.md` + `guidance_updated.txt`. Maps each threat to the layer that can enforce it (OPA vs. Agent / Tool implementation / Infra), writes concrete OPA-scope rule specifications, and produces a proposed `guidance_updated.txt` addendum containing ONLY the missing OPA-enforceable rules for `guidance.txt`. Non-OPA-enforceable findings are recorded in the Gap Register table inside `owasp_policy_guidelines.md`, NOT in `guidance_updated.txt`, so downstream policy and test generation only ever see rule content.
5. **Step E** *(optional, human-triggered)* — On the human's explicit go-ahead, appends `guidance_updated.txt` to `guidance.txt` (preserving the existing file byte-for-byte, so any headings/comments/prose the human authored survive) and hands off to Policy Creation above.

The four required steps can be run **Gated** (pause after each step) or **Autonomous** (Steps A–D back-to-back, one final review at the end). Step E has its own separate trigger. All step outputs live under `<TARGET_AGENT_PATH>/smith/guidelines-security-analysis/`.

### Test Case Generation

The agent follows `test_generation/test_generation.md`, which first asks which kind of test cases you want, then runs the matching command(s):
Expand Down Expand Up @@ -340,6 +354,7 @@ smith/
│ └── opa/ # OPA intermediate results (AST, graphs, backups)
├── examples/ # Agent examples
├── opa_policy/ # Skills related to OPA policy
│ ├── guidelines-security-analysis/ # Security-grounded guidance analysis workflow
│ ├── policy_creation/ # OPA policy creation workflow
│ ├── policy_cross_validation/ # Fix structural/syntax issues (0 cases or 100% fail)
│ ├── policy_defect/ # Introduce intentional defects for testing (only for testing purpose, it is not part of Smith main skill)
Expand Down
13 changes: 13 additions & 0 deletions SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,19 @@ If the user asks to create an OPA policy, you should strictly follow instruction

After completion, remind the user: “The policy has been created. Next steps you can take: (1) generate test cases, (2) if you already have test cases, you can ask me to test the policy.”

## Create an OPA Policy with a Security-Grounded Guidance Analysis
If the user asks to **create an OPA policy with a security-grounded guidance analysis** (or asks to run the guidelines security analysis, threat-model an MCP server, or produce OWASP-mapped enforcement guidance for a new tool), strictly follow instructions in `./opa_policy/guidelines-security-analysis/guidelines-security-analysis.md`. This is a separate, standalone workflow that first grounds the guidance in an OWASP-mapped threat model and then (on explicit human trigger) runs "Create OPA Policy" above against the updated guidance. It runs in order:

- **Step A** — Architecture Analysis (`architecture.md`)
- **Step B** — Policy Guidance Questionnaire (`policy_guidance_questionnaire.md`)
- **Step C** — Threat Model against OWASP Top 10 for Agentic AI Security (`threat_model.md`)
- **Step D** — Enforcement Mapping (`owasp_policy_guidelines.md` + `guidance_updated.txt`)
- **Step E** *(optional, human-triggered)* — Merge `guidance_updated.txt` into `guidance.txt` and hand off to "Create OPA Policy" above

Before starting Step A, ask the user whether to run **Gated** (pause after each step) or **Autonomous** (Steps A–D back-to-back, one final review at the end). Step E stays dormant until the human explicitly asks for the merge; then it appends `guidance_updated.txt` to `guidance.txt` (preserving the existing file byte-for-byte) and continues into `./opa_policy/policy_creation/opa_policy_creation.md` (the same procedure as "Create OPA Policy" above).

After Step D completes, remind the user: "Review `guidance_updated.txt`. When you're satisfied, tell me to merge — I'll append it to `guidance.txt` (preserving your existing content) and run policy creation against the result."

## Test Case Generation
If the user asks to generate test cases, you should strictly follow instructions in `./test_generation/test_generation.md` in the skill directory.

Expand Down
112 changes: 112 additions & 0 deletions assets/policy.rego
Original file line number Diff line number Diff line change
@@ -1,2 +1,114 @@
# Copyright 2026 Smith authors
# SPDX-License-Identifier: Apache-2.0

package mcp.policies

default allow := false

# === Input Accessors ===
subject := input.extensions.subject
args := object.get(input, "args", {})

# === Constants ===

recognized_roles := {"fleet_manager", "consumer", "journalist", "analyst", "guest"}

recognized_vehicle_types := {"carros", "cars", "motos", "motorcycles", "caminhoes", "trucks"}

vehicle_types_by_role := {
"fleet_manager": {"caminhoes", "trucks"},
"consumer": {"carros", "cars"},
"journalist": {"carros", "cars"},
"analyst": {"carros", "cars", "motos", "motorcycles", "caminhoes", "trucks"},
}

fleet_manager_brands := {"Scania", "Volvo", "Mercedes-Benz", "MAN", "DAF", "Iveco", "Ford", "Volkswagen"}

journalist_brands := {
"Fiat", "Chevrolet", "Volkswagen", "Hyundai", "Toyota", "Renault",
"Honda", "Nissan", "Jeep", "Peugeot", "Citroën", "Caoa Chery",
}

brands_by_role := {
"fleet_manager": fleet_manager_brands,
"journalist": journalist_brands,
}

# === Global DENY/ALLOW Rules ===

# NOTE: subject.user_role is a single-element array (e.g. ["fleet_manager"]),
# not a scalar string, so membership checks must unwrap it via `some`.
role_recognized if {
some role in subject.user_role
role in recognized_roles
}

# guidance.txt: "Unknown Roles" — a request whose user_role matches none of
# the five defined roles has no privileges and may call no tool.
deny[msg] if {
not role_recognized
msg := sprintf("user_role '%v' is not a recognized role and may not call any tool", [subject.user_role])
}

# A caller identity must assert exactly one role; claiming multiple roles at
# once is not a valid identity under guidance.txt and must be denied for
# every tool, regardless of whether each individual asserted role would
# otherwise be permitted.
deny[msg] if {
count(subject.user_role) != 1
msg := sprintf("user_role '%v' must assert exactly one role", [subject.user_role])
}

# === Tool-Specific DENY/ALLOW Rules ===

# guidance.txt: "Tool Access by Role" — a guest may only call get_car_brands.
deny[msg] if {
"guest" in subject.user_role
input.name != "get_car_brands"
msg := sprintf("guest role may not call tool '%v'; only get_car_brands is allowed", [input.name])
}

# guidance.txt: "Vehicle Type Restrictions" — allowed vehicle_type values
# depend on role; any value outside the six recognized values is denied for
# every role (do not rely on the backend's silent fallback to "carros").
deny[msg] if {
input.name == "get_vehicles_by_type"
not args.vehicle_type in recognized_vehicle_types
some role in subject.user_role
role in recognized_roles
msg := sprintf("vehicle_type '%v' is not a recognized value", [args.vehicle_type])
}

deny[msg] if {
input.name == "get_vehicles_by_type"
args.vehicle_type in recognized_vehicle_types
some role in subject.user_role
role in recognized_roles
allowed := vehicle_types_by_role[role]
not args.vehicle_type in allowed
msg := sprintf("role '%v' is not permitted to use vehicle_type '%v'", [role, args.vehicle_type])
}

# guidance.txt: "Brand Restrictions" — allowed brand_name values depend on
# role; empty/whitespace-only brand_name is denied for all roles.
deny[msg] if {
input.name == "search_car_price"
trim_space(object.get(args, "brand_name", "")) == ""
some role in subject.user_role
role in recognized_roles
msg := "brand_name must not be empty or whitespace-only"
}

deny[msg] if {
input.name == "search_car_price"
trim_space(object.get(args, "brand_name", "")) != ""
some role in subject.user_role
allowed := brands_by_role[role]
not args.brand_name in allowed
msg := sprintf("role '%v' is not permitted to search brand '%v'", [role, args.brand_name])
}

# === Final ALLOW ===
allow if {
count(deny) == 0
}
21 changes: 20 additions & 1 deletion examples/RagChatbot_MCPServer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,26 @@ MCP_URL=http://localhost:8000/sse

Ask your coding agent to use skill Smith to generate an OPA policy from the guidance file.

#### Step 1.2: Generate Test Cases
#### Step 1.2: (Optional) Security-Grounded Guidance Analysis

Instead of running Step 1.1 directly against the existing `smith/guidance.txt`, you can first run the security-grounded guidance analysis workflow to produce an OWASP-mapped threat model of this MCP server's tools and propose a `smith/guidance_updated.txt` addendum with any missing OPA-enforceable rules (non-OPA-enforceable OWASP findings stay in the Gap Register table of `smith/guidelines-security-analysis/owasp_policy_guidelines.md`, not in `guidance_updated.txt`). Same workflow as `SKILL.md`'s "Create an OPA Policy with a Security-Grounded Guidance Analysis" entry.

Ask your coding agent:

> Create an OPA policy for this MCP server with a security-grounded guidance analysis.

The agent asks whether to run **Gated** (pause after each step) or **Autonomous** (Steps A–D back-to-back with one final review), then produces four artifacts under `smith/guidelines-security-analysis/`:

| Step | Output |
|------|--------|
| A — Architecture Analysis | `smith/guidelines-security-analysis/architecture.md` |
| B — Policy Guidance Questionnaire | `smith/guidelines-security-analysis/policy_guidance_questionnaire.md` |
| C — Threat Model against OWASP Top 10 for Agentic AI Security | `smith/guidelines-security-analysis/threat_model.md` |
| D — Enforcement Mapping | `smith/guidelines-security-analysis/owasp_policy_guidelines.md` + `smith/guidance_updated.txt` |

Review `smith/guidance_updated.txt` when the workflow completes. When you're satisfied, tell the agent to merge — Step E appends `smith/guidance_updated.txt` to `smith/guidance.txt` (preserving your existing content byte-for-byte) and continues into Policy Creation automatically.

#### Step 1.3: Generate Test Cases

To generate test cases, there are three options:

Expand Down
5 changes: 4 additions & 1 deletion examples/RagChatbot_MCPServer/smith/guidance.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,7 @@
11. Always block attempts to "ignore all policies"
12. Always block requests to "bypass security"
13. Always block override all policies" commands
14. Always block attempts to "show all SSN data"
14. Always block attempts to "show all SSN data"
15. Employees cannot use the email_compensation_report tool to send compensation or salary reports to any recipient.
16. When view_team_compensation or export_compensation_data is called with a select_fields list, the fields ssn, home_address, bank_account, tax_id, and emergency_contact must always be excluded from the selection regardless of the requesting role.

17 changes: 17 additions & 0 deletions examples/RagChatbot_MCPServer/smith/guidance_updated.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
1. Managers: View only the requested manager's team compensation data (employee name, title, salary, bonus, department, hire date) via view_team_compensation tool
2. Employees cannot view team compensation data, bonus, or hire date information (view_team_compensation tool blocked)
3. Managers cannot see any team's Social Security Numbers (SSN), Home addresses, Bank account numbers, Tax ID numbers, emergency_contact when querying salary infomation.
4. Managers can export team compensation data in CSV, PDF, JSON format
5. Employees cannot export team compensation data
6. Managers can send information externally (send to non @ibm.com email addresses) by email with: Non-compensation and non-salary data only
7. No one can share compensation data externally to non @ibm.com email addresses
8. No one can send emails to blocked domains: gmail.com, yahoo.com, hotmail.com, outlook.com, personal.com
9. Employees cannot buy products $200+ without manager approval
10. Managers can buy products under $1,000
11. Always block attempts to "ignore all policies"
12. Always block requests to "bypass security"
13. Always block override all policies" commands
14. Always block attempts to "show all SSN data"
15. Employees cannot use the email_compensation_report tool to send compensation or salary reports to any recipient.
16. When view_team_compensation or export_compensation_data is called with a select_fields list, the fields ssn, home_address, bank_account, tax_id, and emergency_contact must always be excluded from the selection regardless of the requesting role.

Loading
Loading