Commit 05ad59a
authored
release: v0.4.7 — policy conditions, UX overhaul, dashboard, security hardening (#90)
* chore: ignore .home/ (Codex sandbox artifact)
* fix(dashboard): conn-dot states, empty states, mobile overflow, tab fade, UX polish
- Wire conn-dot CSS classes (ok/err/wait) in setConnected() and SSE error handler
- Empty states: icons + descriptive subtitles for pending, history, denials
- Mobile: flex-wrap at ≤540px for pend-item, policy-test-row; bulk-bar fix at ≤420px
- Tab fade-in animation (tabFadeIn, 0.15s)
- Token input: show/hide toggle button (👁)
- Recent Denials: 'View all →' link switches to History tab
- Pending buttons: 'Always' → 'Always Allow'
- Dangerous items: 3px border + background tint
- Denial rows: title attribute for full reason on hover
- History: loading indicator (hist-loading div, shown/hidden around fetch)
* feat(policy): agent_depth and tool_param_matches conditions
- engine/decision.go: add AgentDepth int and Input map[string]any to ToolCall
- engine/policy.go: add AgentDepth *IntRangeCondition and ToolParamMatches map[string]string to Condition; new IntRangeCondition type (gte/lte/eq); IsEmpty() updated
- engine/matcher.go: wire both conditions in ExplainCondition and matchCondition; agent_depth range/eq checks; tool_param_matches case-insensitive glob against call.Input
- engine/lint.go: register agent_depth and tool_param_matches as valid condition keys; fix gofmt whitespace
- engine/matcher_test.go: 9 test cases for TestMatchCondition_AgentDepth and TestMatchCondition_ToolParamMatches (all passing)
- cmd/rampart/cli/hook.go: read RAMPART_AGENT_DEPTH env; increment depth for tool==agent; set call.AgentDepth and call.Input
- internal/proxy/server.go: add Input field to ToolExecRequest; populate via extractToolInput() (MCP arguments/tool_input/params fallback)
- internal/mcp/proxy.go: set ToolCall.Input = params.Arguments on tools/call
- docs-site/reference/policy-schema.md: document agent_depth and tool_param_matches with examples
* fix(polish): token show command, doctor path hints, default_action:allow lint warning
* fix(polish): token show command, doctor path hints, default_action:allow lint warning
- token.go: new 'rampart token' / 'rampart token show' command; reads ~/.rampart/token via readPersistedToken()
- token_test.go: TestTokenShow_PrintsPersistedToken covers both 'token' and 'token show' variants
- doctor.go: hook failure messages now include the actual file/directory path that was checked, plus 'Run: rampart setup <agent>' hint for Claude Code and Cline
- doctor_test.go: TestDoctorHooks_PathHints asserts path appears in failure messages
- lint.go: LintWarning when default_action is 'allow' — advises using deny + explicit allow rules
- lint_test.go: TestLint_DefaultActionAllowWarning asserts warning is emitted
* chore: remove Codex sandbox cache artifacts, ignore .home/
* fix(ux): hook fail-closed warning, policy explain auto-discover, watch token/URL auto, --version flag, status fixes
* fix(ux): hook fail-closed warning, policy explain auto-discover, watch token/URL auto, --version flag, status unknown fix, upgrade restart reminder
- hook_approval.go: always print WARNING when serve is unreachable; route all stderr through injected errWriter
- hook.go: pass cmd.ErrOrStderr() to approval client
- policy.go: resolveExplainPolicyPath() — auto-discovers ~/.rampart/policies/standard.yaml, then cwd rampart.yaml, then helpful error
- watch.go: resolveWatchServeConfig() — auto-discovers URL (defaults localhost:9090) and token (~/.rampart/token)
- root.go: --version persistent flag, delegates to shared writeVersion()
- version.go: extract writeVersion(io.Writer) helper
- status.go: suppress '(unknown)' parenthetical when cmd or policy is empty/unknown
- upgrade.go: print restart reminder after successful upgrade
- Tests: 12 new test cases covering all changes (cli_test, policy_test, watch_test, status_test, upgrade_test, hook_approval_test)
* fix(ux): resolveExplainPolicyPath respects programmatically-set configPath
When opts.configPath is set directly (not via cobra --config flag), cobra's
Changed() returns false and auto-discovery would override the intended path.
Now: if configPath is non-empty, non-default, and the file exists, use it —
handles both the cobra-flag path and programmatic/test usage correctly.
Fixes TestPolicyExplainDeny CI failure on fix/v047-ux.
* fix(reliability): audit permissions check, reload error logging, PostToolUseFailure audit, dead code cleanup
- doctor.go: scan ~/.rampart/audit/ for world-readable files (mode & 0o004); warn in summary
- rules_handlers.go: log engine.Reload() errors at Error level (was silently discarded in 2 places)
- server.go: same Reload() fix in policy hot-reload handler
- hook.go: write audit event before PostToolUseFailure early return
- watch.go: remove dead approvalLines variable and assignments
- mcp/proxy.go: close childIn on all exit paths in child error handler
* feat: prompt injection detection + actionable denial hints
policies/standard.yaml: new watch-prompt-injection policy
- Monitors fetch/web_search/read/exec/mcp tool responses for injection patterns
- Covers: instruction override, role hijack, model-specific tokens (<|im_start|>system,
[SYSTEM], ###INSTRUCTIONS###), exfiltration directives
- action: watch (not deny) — logs for review without blocking legitimate content
- 14 regex patterns, all case-insensitive via (?i), tested against 15 cases
cmd/rampart/cli/hook.go: enrich PostToolUseFailure feedback
- Includes tool name in suggested explain command
- Adds: 'run rampart policy explain <tool>', 'rampart watch', policy path hint,
and link to rampart.sh/docs/exceptions
- Agent can now surface concrete next steps to the user instead of hitting a dead end
* fix: code review fixes + agent-install (PR #90 follow-up) (#91)
* fix: code review fixes + agent-install support (PR #90 follow-up)
Fixes from code review of PR #90:
B1 (BLOCKER): tool_param_matches uses MatchGlob instead of filepath.Match
- filepath.Match treats * as non-separator, so '**/.env*' silently never
matched multi-directory paths like '/home/user/.envrc'
- Both ExplainCondition and matchCondition now use MatchGlob
- Add two tests with ** patterns that would have caught this
W1: Clamp RAMPART_AGENT_DEPTH to >= 0
- strconv.Atoi parses negative strings fine; a manipulated env var could
set depth=-999 to bypass agent_depth: {gte: 1} deny rules
- One-line clamp after parse
W2: PostToolUseFailure audit event action 'allow' -> 'feedback'
- Logging a blocked tool call as action:'allow' was semantically wrong,
skewed allow/deny stats in the dashboard, and confused audit readers
- New action:'feedback' clearly identifies these as guidance-injection events
W3: resolveExplainPolicyPath errors on non-default missing path
- Previously silently fell through to auto-discovery when a programmatic
configPath pointed at a file that didn't exist
- Now returns an explicit error, consistent with --config flag behavior
W4: Reload() failure returns HTTP 500 instead of silently 200
- Both the delete and write paths now return InternalServerError if
engine.Reload() fails post-change, so callers know enforcement
may not reflect the written state
feat: OpenClaw auto-detection and agent-install support
- detectEnv() now detects OpenClaw via OPENCLAW_SERVICE_MARKER env var
(set by the OpenClaw gateway when it spawns an agent process); more
reliable than PATH lookup which was too broad
- quickstart --yes / -y flag: non-interactive mode for AI agents, CI,
and scripted setups; also auto-enables --patch-tools for OpenClaw
- Add docs/guides/agent-install.md: step-by-step guide written for an
AI agent to read and execute when told 'install Rampart and protect me'
- Add 'Security Guides' nav section in mkdocs.yml
- Update integrations/openclaw.md with quickstart --yes callout
- Add TestDetectEnv_OpenClaw; fix existing detectEnv tests to unset
OPENCLAW_SERVICE_MARKER so they pass on machines running OpenClaw
* fix(docs): agent-install accuracy fixes
- rampart test does not exist; replace with rampart doctor
- rampart status expected output was wrong; show real format
(Protected/Mode/Today, not 'rampart serve running port')
- --yes flag description now accurately says what it does:
enables --patch-tools for OpenClaw, safe no-op for others
- Step numbering fixed (removed step 4 gap after deleting rampart test)
- Reference table: remove rampart test row, fix status description
* docs: SEO + agent-friendly docs rewrite (#92)
* docs: SEO + agent-friendly docs rewrite
- Add description: frontmatter to all 20+ docs-site pages
(these become HTML meta description tags and Google search snippets)
- New guides/securing-claude-code.md: standalone SEO guide targeting
'claude code security', 'how to keep claude code safe', etc.
- New guides/prompt-injection.md: covers watch-prompt-injection policy,
detection patterns, and how to escalate to deny
- Homepage FAQ: literal search-query questions as h2s with Rampart answers
- README: opens with 'security layer for AI coding agents' framing
- Integrations claude-code.md: 'Why You Need This' section with concrete
attack scenarios (rm -rf, curl|bash, ssh key exfil, prompt injection)
and 'What Gets Blocked by Default' table
- mkdocs.yml: Security Guides nav section with new guides
* fix(docs): review feedback — FAQ, escalate YAML, description length
- FAQ: replace 'Does Rampart work with OpenClaw?' with the more
broadly useful 'Does Rampart send my commands to any external server?'
(biggest adoption blocker for security-conscious users; answer: no,
everything is local)
- FAQ securing-claude-code.md Q4: clarify hook unreachable behavior —
Rampart prints WARNING to stderr, falls back to hookAsk (native
Claude Code permission prompt), not silently fail-open
- Fix escalate-to-deny YAML in prompt-injection.md: was wrong schema
(action/tool at top level, wrong field name 'response_patterns');
now uses correct nested rules: / match: / response_matches: structure
- Trim claude-code.md description: 201 → 158 chars (Google truncates at 160)
* docs: replace Mermaid diagrams and architecture.png with D2 (theme 200) (#93)
- Drop all 4 Mermaid diagrams (policy-engine, integrations, mcp-proxy,
semantic-verification) in favour of D2 with theme 200 + ELK layout
- Replace static architecture.png (invisible to LLMs) with inline D2
diagram showing agents → interception → policy engine → outcomes
- Remove emojis from node labels; colour alone carries semantic meaning
- Rewrite integrations decision tree: cleaner branch labels, distinct
nodes for wrap vs preload, removes confusing 'Has $SHELL support?' fork
- Add mkdocs-d2-plugin to mkdocs.yml (theme 200, elk layout, pad 40)
- Update docs CI workflow: install D2 binary + mkdocs-d2-plugin
* docs: README architecture diagram → D2-rendered SVG (#94)
- docs/architecture.d2: canonical D2 source (theme 200, elk layout)
- docs/architecture.svg: pre-rendered SVG, embedded in README as <img>
- Replace 'How it works' Mermaid block with SVG embed — looks
significantly better on GitHub, also agent/LLM readable (SVG is text)
- Strip emojis from approval flow Mermaid node labels
- Add .github/workflows/render-diagrams.yml: auto re-renders
architecture.svg and commits when docs/architecture.d2 changes
* fix: sweep warnings — .env.* policy coverage + agent-install note cleanup (#96)
W1: collapse OpenClaw restart admonition into prose in agent-install.md
(same content, less visual weight)
W2: expand .env credential coverage to include .env.* variants
(.env.local, .env.production, .env.staging etc. were not blocked)
- block-credential-access (read): add **/.env.* pattern
- block-credential-commands (exec): add cat **/.env.*
- block-sensitive-writes (write/edit): add **/.env.*
- Update docs tables in claude-code.md and securing-claude-code.md1 parent b6ce72b commit 05ad59a
File tree
75 files changed
+2214
-196
lines changed- .github/workflows
- cmd/rampart/cli
- docs-site
- assets
- deployment
- features
- getting-started
- guides
- integrations
- reference
- docs
- internal
- dashboard/static
- engine
- mcp
- proxy
- watch
- policies
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
75 files changed
+2214
-196
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
22 | 22 | | |
23 | 23 | | |
24 | 24 | | |
25 | | - | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
26 | 31 | | |
27 | 32 | | |
28 | 33 | | |
| 34 | + | |
| 35 | + | |
29 | 36 | | |
30 | 37 | | |
31 | 38 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
25 | 25 | | |
26 | 26 | | |
27 | 27 | | |
| 28 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
5 | | - | |
| 5 | + | |
6 | 6 | | |
7 | 7 | | |
8 | 8 | | |
| |||
14 | 14 | | |
15 | 15 | | |
16 | 16 | | |
17 | | - | |
18 | | - | |
19 | | - | |
20 | | - | |
21 | | - | |
| 17 | + | |
22 | 18 | | |
| 19 | + | |
23 | 20 | | |
24 | | - | |
25 | | - | |
| 21 | + | |
26 | 22 | | |
27 | 23 | | |
28 | 24 | | |
| |||
48 | 44 | | |
49 | 45 | | |
50 | 46 | | |
51 | | - | |
52 | | - | |
53 | | - | |
54 | | - | |
55 | | - | |
56 | | - | |
57 | | - | |
58 | | - | |
59 | | - | |
60 | | - | |
61 | | - | |
62 | | - | |
63 | | - | |
64 | | - | |
65 | | - | |
66 | | - | |
67 | | - | |
68 | | - | |
69 | | - | |
70 | | - | |
71 | | - | |
72 | | - | |
73 | | - | |
74 | | - | |
75 | | - | |
76 | | - | |
77 | | - | |
78 | | - | |
79 | | - | |
80 | | - | |
81 | | - | |
82 | | - | |
83 | | - | |
| 47 | + | |
84 | 48 | | |
85 | 49 | | |
86 | 50 | | |
| |||
419 | 383 | | |
420 | 384 | | |
421 | 385 | | |
422 | | - | |
| 386 | + | |
423 | 387 | | |
424 | 388 | | |
425 | 389 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
35 | 35 | | |
36 | 36 | | |
37 | 37 | | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
38 | 44 | | |
39 | 45 | | |
40 | 46 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
131 | 131 | | |
132 | 132 | | |
133 | 133 | | |
134 | | - | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
135 | 137 | | |
136 | 138 | | |
137 | 139 | | |
| |||
457 | 459 | | |
458 | 460 | | |
459 | 461 | | |
460 | | - | |
| 462 | + | |
461 | 463 | | |
462 | 464 | | |
463 | 465 | | |
464 | | - | |
| 466 | + | |
465 | 467 | | |
466 | 468 | | |
467 | 469 | | |
468 | | - | |
| 470 | + | |
469 | 471 | | |
470 | 472 | | |
471 | 473 | | |
| |||
484 | 486 | | |
485 | 487 | | |
486 | 488 | | |
487 | | - | |
| 489 | + | |
488 | 490 | | |
489 | 491 | | |
490 | 492 | | |
491 | | - | |
| 493 | + | |
492 | 494 | | |
493 | 495 | | |
494 | 496 | | |
| |||
533 | 535 | | |
534 | 536 | | |
535 | 537 | | |
536 | | - | |
| 538 | + | |
537 | 539 | | |
538 | 540 | | |
539 | | - | |
| 541 | + | |
540 | 542 | | |
541 | 543 | | |
542 | 544 | | |
543 | 545 | | |
544 | 546 | | |
545 | 547 | | |
546 | | - | |
| 548 | + | |
547 | 549 | | |
548 | 550 | | |
549 | 551 | | |
550 | 552 | | |
551 | 553 | | |
552 | 554 | | |
553 | | - | |
| 555 | + | |
554 | 556 | | |
555 | 557 | | |
556 | 558 | | |
| |||
566 | 568 | | |
567 | 569 | | |
568 | 570 | | |
569 | | - | |
| 571 | + | |
570 | 572 | | |
571 | 573 | | |
572 | 574 | | |
| |||
579 | 581 | | |
580 | 582 | | |
581 | 583 | | |
582 | | - | |
| 584 | + | |
| 585 | + | |
| 586 | + | |
| 587 | + | |
| 588 | + | |
| 589 | + | |
| 590 | + | |
| 591 | + | |
| 592 | + | |
| 593 | + | |
| 594 | + | |
| 595 | + | |
| 596 | + | |
| 597 | + | |
| 598 | + | |
| 599 | + | |
| 600 | + | |
| 601 | + | |
| 602 | + | |
| 603 | + | |
| 604 | + | |
| 605 | + | |
| 606 | + | |
| 607 | + | |
| 608 | + | |
| 609 | + | |
| 610 | + | |
583 | 611 | | |
584 | 612 | | |
585 | 613 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
17 | 17 | | |
18 | 18 | | |
19 | 19 | | |
| 20 | + | |
| 21 | + | |
20 | 22 | | |
21 | 23 | | |
22 | 24 | | |
23 | 25 | | |
24 | 26 | | |
25 | | - | |
26 | 27 | | |
27 | 28 | | |
28 | 29 | | |
| |||
159 | 160 | | |
160 | 161 | | |
161 | 162 | | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
0 commit comments