Skip to content

Commit f4e2c72

Browse files
authored
docs: overhaul navigation and docs experience (#9)
Signed-off-by: Luca Muscariello <muscariello@ieee.org>
1 parent 3ae096d commit f4e2c72

File tree

18 files changed

+910
-96
lines changed

18 files changed

+910
-96
lines changed

Justfile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,11 @@ secops-approve-prs:
9797
secops-test-python:
9898
uv run --with pytest pytest agents/secops/tests/test_skills.py
9999

100+
secops-skill-scan:
101+
rm -rf .tmp/skill-scanner/secops
102+
uv run --no-project --python .venv/bin/python tools/prepare_skill_scan.py --source agents/secops --dest .tmp/skill-scanner/secops
103+
uvx --from cisco-ai-skill-scanner skill-scanner scan .tmp/skill-scanner/secops --format summary --format markdown --detailed --output-markdown .tmp/skill-scanner/secops-scan.md
104+
100105
secops-a2a:
101106
uv run --no-project --python .venv/bin/python agents/secops/a2a_server.py
102107

README.md

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,14 @@ SHADI is designed for environments where agents are long-lived, hold real creden
1212
- SQLCipher-backed encrypted local memory (`shadi_memory`).
1313
- Python bindings (`shadi_py`) for secrets, memory, and sandboxed execution.
1414
- SLIM transport integration for secure agent-to-agent messaging.
15-
- A practical SecOps agent demo and launch scripts.
15+
- Example agents and demos, including a practical SecOps workflow and launch scripts.
16+
17+
Recent updates in this branch of the project:
18+
19+
- SecOps now treats container CVEs as rebuild or base-image refresh work instead of mutating Dockerfiles with ad-hoc package upgrade lines.
20+
- Dockerfile resolution for container findings is workflow-first, using `.github/workflows/*` metadata before repo-wide scanning.
21+
- Demo launchers are hardened for the optional 1Password backend by reading required secrets before entering the sandbox.
22+
- Avatar surfaces clearer SLIM handshake errors when the SecOps A2A side is unavailable or misconfigured.
1623

1724
## Repository layout
1825

@@ -22,7 +29,7 @@ SHADI is designed for environments where agents are long-lived, hold real creden
2229
- `crates/shadi_memory`: SQLCipher memory library and CLI (`shadi-memory`).
2330
- `crates/shadi_py`: Python extension module `shadi`.
2431
- `crates/agent_transport_slim` + `crates/slim_mas`: secure transport and moderation helpers.
25-
- `agents/secops`: SecOps agent, A2A server, and skill implementation.
32+
- `agents/secops`: example SecOps workload, A2A server, and skill implementation.
2633
- `docs`: architecture, security, CLI, demos, and integration docs.
2734
- `scripts`: local launch helpers for SLIM + agent demos.
2835

@@ -141,7 +148,7 @@ The module exposes bindings for:
141148

142149
## SecOps demo and launch scripts
143150

144-
The repo includes runnable examples under `agents/secops` and helper scripts in `scripts/`.
151+
The repo includes runnable demo workloads under `agents/secops` and helper scripts in `scripts/`.
145152

146153
Common local flow:
147154

@@ -152,6 +159,18 @@ Common local flow:
152159
./scripts/launch_avatar.sh
153160
```
154161

162+
Focused Python tests for the SecOps skill:
163+
164+
```bash
165+
just secops-test-python
166+
```
167+
168+
Security scan for the SecOps skill package:
169+
170+
```bash
171+
just secops-skill-scan
172+
```
173+
155174
See `scripts/README.md` and `docs/demo.md` for full setup details.
156175

157176
## Documentation
@@ -164,6 +183,7 @@ Primary docs live in `docs/`:
164183
- `docs/cli.md`: complete CLI reference
165184
- `docs/sandbox.md`: policy model and profile behavior
166185
- `docs/demo.md`: demo walkthrough
186+
- `docs/secops_agent.md`: SecOps demo workload and remediation behavior
167187

168188
Build/serve docs locally:
169189

docs/api_integration.md

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ To list secrets stored for an app or agent, use `shadictl`:
3232

3333
```bash
3434
cargo run -p shadictl -- --list-keychain --list-prefix agents/
35-
cargo run -p shadictl -- --list-keychain --list-prefix secops/
35+
cargo run -p shadictl -- --list-keychain --list-prefix apps/
3636
```
3737

3838
Avoid printing secret values. Pass key names to helpers that resolve secrets
@@ -45,14 +45,14 @@ To list or search long-term memory in the encrypted SQLCipher store, use the
4545
cargo run -p shadictl -- -- memory list \
4646
--db "${SHADI_TMP_DIR:-./.tmp}/shadi-memory.db" \
4747
--key-name shadi/memory/sqlcipher_key \
48-
--scope secops --limit 50
48+
--scope app --limit 50
4949
```
5050

5151
```bash
5252
cargo run -p shadictl -- -- memory search \
5353
--db "${SHADI_TMP_DIR:-./.tmp}/shadi-memory.db" \
5454
--key-name shadi/memory/sqlcipher_key \
55-
--scope secops --query dependabot --limit 10
55+
--scope app --query policy --limit 10
5656
```
5757

5858
## Integration overview
@@ -103,8 +103,8 @@ fn main() -> Result<(), SecretError> {
103103
let mut session = SessionContext::new("agent-1", "session-1");
104104
session.verified = true;
105105

106-
access.put_for_session(&session, "secops/token", b"secret", SecretPolicy::default())?;
107-
let secret = access.get_for_session(&session, "secops/token")?;
106+
access.put_for_session(&session, "app/config", b"secret", SecretPolicy::default())?;
107+
let secret = access.get_for_session(&session, "app/config")?;
108108
let value = secret.expose(|bytes| bytes.to_vec());
109109

110110
println!("secret len: {}", value.len());
@@ -157,9 +157,9 @@ store.set_verifier(lambda agent_id, session_id, presentation, claims: True)
157157
session = PySessionContext("agent-1", "session-1")
158158
store.verify_session(session, b"didvc-presentation")
159159

160-
store.put(session, "secops/token", b"secret")
161-
print(store.get(session, "secops/token"))
162-
store.delete(session, "secops/token")
160+
store.put(session, "app/config", b"secret")
161+
print(store.get(session, "app/config"))
162+
store.delete(session, "app/config")
163163
```
164164

165165
### Example: integrate with an app session
@@ -196,12 +196,12 @@ store.put(session, "app/config", b"value")
196196
from shadi import SqlCipherMemoryStore
197197

198198
store = SqlCipherMemoryStore(
199-
db_path="./.tmp/shadi-secops/secops_memory.db",
200-
key_name="secops/memory_key",
199+
db_path="./.tmp/shadi-app/app_memory.db",
200+
key_name="app/memory_key",
201201
)
202202

203-
store.put("secops", "security_report", "{\"status\":\"ok\"}")
204-
latest = store.get_latest("secops", "security_report")
203+
store.put("app", "latest_state", "{\"status\":\"ok\"}")
204+
latest = store.get_latest("app", "latest_state")
205205
print(latest.payload if latest else "no entry")
206206
```
207207

@@ -286,7 +286,7 @@ access to the agent sessions.
286286
## Secret store naming in Rust vs Python
287287

288288
Rust and Python use the same underlying SHADI secret store. The "name" you see
289-
in examples is just the secret key string (for example, `secops/token` or
289+
in examples is just the secret key string (for example, `app/config` or
290290
`agents/agent-a/did`). There is no separate store per language.
291291

292292
If you see different names between Rust and Python examples, it is only a
@@ -313,8 +313,8 @@ For Python agents, you can run under the sandbox using the JSON policy runner:
313313

314314
```bash
315315
./.venv/bin/python tools/run_sandboxed_agent.py \
316-
--policy policies/demo/secops-a.json \
317-
-- ./.venv/bin/python agents/secops/a2a_server.py
316+
--policy ./sandbox.json \
317+
-- ./.venv/bin/python ./your_agent.py
318318
```
319319

320320
`net_allow` in the policy file is enforced by the Python runner using a
@@ -325,7 +325,7 @@ sandbox and inject it as an environment variable:
325325

326326
```bash
327327
cargo run -p shadictl -- \
328-
--inject-keychain secops/token=GITHUB_TOKEN \
328+
--inject-keychain app/config=APP_CONFIG \
329329
-- \
330330
./your-agent
331331
```

docs/architecture.md

Lines changed: 82 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,11 @@ actions and prevent unauthorized data access or exfiltration.
5656
### 2) Sandbox layer
5757
- **macOS**: Seatbelt profile enforcement for filesystem and network policies.
5858
- **Windows**: AppContainer + ACL allowlists + Job Objects (kill-on-close).
59-
- **CLI**: `shadi` provides command blocklists and a JSON policy format.
59+
- **CLI**: `shadi` provides JSON policy loading, profile defaults, optional command blocklists, and brokered secret injection.
6060
- **Portable launcher model**: `shadi` supports built-in profiles
6161
(`strict`, `balanced`, `connected`) for portable secure launch defaults.
62+
- **Launch-time enforcement**: Policy is resolved before the agent process starts, so the sandbox is not a prompt-level suggestion that the agent can rewrite from inside the session.
63+
- **Operational hardening**: macOS launcher support now resolves relative paths before emitting Seatbelt rules and accounts for required local IPC paths such as 1Password and SLIM runtime state.
6264

6365
#### Key modules
6466
- `crates/shadi_sandbox/src/policy.rs`: policy model and helpers.
@@ -68,14 +70,14 @@ actions and prevent unauthorized data access or exfiltration.
6870
### 3) Memory layer
6971
- **Local encrypted store**: SQLCipher-backed SQLite for portable, on-device memory.
7072
- **Key management**: Encryption keys live in SHADI secrets (keychain backed).
71-
- **Agent usage**: SecOps writes summaries to the encrypted store; ADK memory remains in-process unless configured for persistent backends.
73+
- **Agent usage**: workloads running on SHADI can persist local state in the encrypted store; the SecOps demo writes summaries there, while ADK memory remains in-process unless configured for persistent backends.
7274

7375
#### Key modules
7476
- `crates/shadi_memory/src/lib.rs`: SQLCipher store and query helpers.
7577
- `crates/shadi_memory/src/main.rs`: shadi-memory CLI.
7678
- `crates/shadictl/src/main.rs`: `shadictl memory` helper.
7779
- `crates/shadi_py/src/lib.rs`: SQLCipher bindings.
78-
- `agents/secops/skills.py`: SecOps summary persistence.
80+
- `agents/secops/skills.py`: example summary persistence used by the SecOps demo.
7981

8082
### 4) Transport layer
8183
- **SLIM/A2A**: MLS provides confidentiality and integrity between agents.
@@ -87,6 +89,9 @@ actions and prevent unauthorized data access or exfiltration.
8789
### 5) Brokered secret injection (optional)
8890
- If sandbox rules prevent keystore access, secrets can be brokered outside the
8991
sandbox and injected as environment variables into the agent process.
92+
- This is also the fallback path used by the demo launchers when the optional
93+
1Password backend is enabled: required items are read in the foreground and
94+
exported into the sandboxed process environment.
9095

9196
#### Key modules
9297
- `crates/shadictl/src/main.rs`: `--inject-keychain` and policy enforcement.
@@ -114,9 +119,10 @@ The CLI combines profile defaults, policy file settings, and explicit flags:
114119
- CLI flags override or extend resulting policy.
115120
- The effective policy can be printed with `--print-policy`.
116121

117-
## SecOps agent architecture
118-
The SecOps agent runs locally under SHADI and uses the Python bindings for secrets
119-
plus GitHub APIs for security signals.
122+
## Demo workload: SecOps agent
123+
The SecOps agent is an example workload that runs on top of SHADI. It uses the
124+
Python bindings for secrets plus GitHub APIs for security signals, but it is
125+
not part of the core runtime itself.
120126

121127
#### Key modules
122128
- `agents/secops/skills.py`: skills to collect alerts and issues.
@@ -128,7 +134,71 @@ plus GitHub APIs for security signals.
128134
1. Read config from secops.toml.
129135
2. Fetch GitHub token and workspace path from SHADI.
130136
3. Collect Dependabot alerts and security-labeled issues.
131-
4. Write `secops_security_report.json` to the workspace.
137+
4. Collect code-scanning alerts for container findings via GitHub code scanning.
138+
5. For dependency alerts, patch supported manifests and stage repo-relative changes.
139+
6. For container CVEs, locate the authoritative Dockerfile from GitHub workflow metadata when possible and recommend image rebuilds or base-image refreshes instead of ad-hoc package-install edits.
140+
7. Create remediation issues and optional PRs, then write `secops_security_report.json` to the workspace.
141+
142+
## Updated system view
143+
144+
```mermaid
145+
flowchart TB
146+
subgraph Operator[Operator and Control Plane]
147+
Human[Human operator]
148+
Config[secops.toml and policy JSON]
149+
Launchers[Launch scripts and shadictl]
150+
end
151+
152+
subgraph Trust[Identity and Secret Plane]
153+
Verify[PySessionContext and verifier]
154+
Secrets[ShadiStore]
155+
Keychain[OS keychain or 1Password backend]
156+
MemoryKey[SQLCipher memory key]
157+
end
158+
159+
subgraph Runtime[Sandboxed Runtime Plane]
160+
Sandbox[shadi_sandbox policy enforcement]
161+
Avatar[Avatar ADK agent]
162+
SecOps[SecOps agent or A2A server]
163+
Memory[SqlCipherMemoryStore]
164+
end
165+
166+
subgraph External[External Services]
167+
GitHub[GitHub APIs and gh CLI]
168+
Models[LLM provider endpoints]
169+
SLIM[SLIM or A2A transport]
170+
end
171+
172+
Human --> Launchers
173+
Config --> Launchers
174+
Launchers --> Sandbox
175+
Human --> Verify
176+
Verify --> Secrets
177+
Secrets --> Keychain
178+
Secrets --> MemoryKey
179+
Sandbox --> Avatar
180+
Sandbox --> SecOps
181+
Avatar --> SLIM
182+
SecOps --> SLIM
183+
SecOps --> GitHub
184+
SecOps --> Models
185+
SecOps --> Memory
186+
MemoryKey --> Memory
187+
Avatar -. verified secret reads .-> Secrets
188+
SecOps -. verified secret reads .-> Secrets
189+
```
190+
191+
The main architecture update is that SHADI now has a clearer split between:
192+
- control-plane launch logic that resolves policy and optional secret brokerage before process start,
193+
- runtime enforcement that the agent cannot weaken by rewriting a local denylist path string,
194+
- and application-layer behavior implemented by example workloads such as SecOps remediation planning and Avatar-to-SecOps orchestration.
195+
196+
## Demo workload behavior: SecOps remediation model
197+
198+
- Dependency remediation still edits supported manifests directly and can open PRs.
199+
- Container CVEs are handled as rebuild guidance, not by mutating Dockerfiles with ad-hoc OS package commands.
200+
- Dockerfile discovery prefers `.github/workflows/*` as the authoritative source of build definitions, then falls back to portable filesystem scanning.
201+
- If only guidance is needed, SecOps opens a remediation issue so the repo owner can refresh the base image or rebuild the container in the right place.
132202

133203
## Data flow (high level)
134204
1. Human identity material is ingested (OpenPGP or seed bytes).
@@ -210,8 +280,9 @@ flowchart LR
210280
- **Stopped**: Message tampering; MLS provides integrity/authentication.
211281

212282
### Privilege escalation
213-
- **Stopped**: Running blocked commands via CLI blocklist.
214-
- **Mitigated**: Kernel-level constraints remain even if the agent tries to evade.
283+
- **Mitigated**: Prompt-level or path-level agent reasoning by applying sandbox policy before launch.
284+
- **Mitigated**: Running blocked commands via CLI blocklist when that feature is used.
285+
- **Mitigated**: Kernel-level constraints remain even if the agent tries to evade application-layer logic.
215286

216287
## Threat-to-control mapping
217288

@@ -221,7 +292,7 @@ flowchart LR
221292
| Secret theft at rest | OS keystore storage | Blocked |
222293
| Secret exfiltration in sandbox | OS sandbox + net block | Blocked |
223294
| Unauthorized file access | Seatbelt/AppContainer allowlists | Blocked |
224-
| Destructive commands | CLI blocklist | Blocked |
295+
| Destructive commands | CLI blocklist | Mitigated |
225296
| Message interception | MLS in SLIM | Blocked |
226297
| Message tampering | MLS integrity | Blocked |
227298
| Agent identity substitution | HKDF derivation + verify-agent-identity | Blocked (with verification) |
@@ -231,6 +302,7 @@ flowchart LR
231302
- Host OS compromise or kernel-level malware can bypass sandbox controls.
232303
- Metadata leakage (timing, sizes, endpoints) is not fully addressed in v1.
233304
- ACL changes on Windows could be interrupted before rollback in a crash.
305+
- Application-level path deny rules are weaker than OS-enforced sandbox restrictions; do not rely on path matching alone for high-assurance policy.
234306

235307
## Deployment guidance
236308
- Prefer running agents under the sandbox with a JSON policy file.

docs/assets/img/logo-dark.svg

Lines changed: 3 additions & 0 deletions
Loading

docs/assets/img/logo-light.svg

Lines changed: 3 additions & 0 deletions
Loading

0 commit comments

Comments
 (0)