|
| 1 | +# 🎨 SpiceDB Permission Trace HTML Examples |
| 2 | + |
| 3 | +Interactive HTML visualizations of SpiceDB permission traces generated by the `zed` CLI tool. |
| 4 | + |
| 5 | +## 🚀 Quick Start |
| 6 | + |
| 7 | +Open **`index.html`** in your browser to view all examples, or jump directly to individual files below. |
| 8 | + |
| 9 | +--- |
| 10 | + |
| 11 | +## 📂 Example Files |
| 12 | + |
| 13 | +### Example 1: Simple Has Permission ✅ |
| 14 | + |
| 15 | +**File**: `example1_simple_has_permission.html` |
| 16 | + |
| 17 | +Basic permission check that succeeds with clean visualization. |
| 18 | + |
| 19 | +- **Scenario**: `document:report-2024` → `view` → `user:alice` |
| 20 | +- **Result**: ✓ Has Permission (green icon) |
| 21 | +- **Features**: Metadata header, subject display, duration tracking |
| 22 | + |
| 23 | +### Example 2: No Permission ⨉ |
| 24 | + |
| 25 | +**File**: `example2_no_permission.html` |
| 26 | + |
| 27 | +Permission denied with faint styling to de-emphasize the failure. |
| 28 | + |
| 29 | +- **Scenario**: `document:secret-plans` → `admin` → `user:bob` |
| 30 | +- **Result**: ⨉ No Permission (red icon) |
| 31 | +- **Features**: Red icon, faint text, clear denial indicator |
| 32 | + |
| 33 | +### Example 3: Nested with Cache 🏎️ |
| 34 | + |
| 35 | +**File**: `example3_nested_with_cache.html` |
| 36 | + |
| 37 | +Hierarchical permission resolution showing cache optimization. |
| 38 | + |
| 39 | +- **Scenario**: `document:quarterly-report` → `folder:documents` (cached) |
| 40 | +- **Result**: ✓ Has Permission with cache badge |
| 41 | +- **Features**: Expandable tree, "cached by spicedb" badge, relation color coding |
| 42 | + |
| 43 | +### Example 4: Conditional with Caveat ✅? |
| 44 | + |
| 45 | +**File**: `example4_conditional_with_caveat.html` |
| 46 | + |
| 47 | +Permission granted after evaluating a caveat expression. |
| 48 | + |
| 49 | +- **Scenario**: `document:internal-roadmap` with `engineering_clearance` caveat |
| 50 | +- **Expression**: `department == "engineering" && clearance_level >= 3` |
| 51 | +- **Context**: JSON showing `{"department": "engineering", "clearance_level": 3}` |
| 52 | +- **Features**: Caveat evaluation, expression display, pretty-printed JSON context |
| 53 | + |
| 54 | +### Example 5: Missing Context ? |
| 55 | + |
| 56 | +**File**: `example5_missing_context.html` |
| 57 | + |
| 58 | +Permission check requires context that wasn't provided. |
| 59 | + |
| 60 | +- **Scenario**: `document:sensitive-data` with `secure_access` caveat |
| 61 | +- **Missing**: `ip_address`, `mfa_verified` |
| 62 | +- **Features**: Purple ? icon, list of missing required fields |
| 63 | + |
| 64 | +### Example 6: Complex Hierarchy 🌳 |
| 65 | + |
| 66 | +**File**: `example6_complex_hierarchy.html` |
| 67 | + |
| 68 | +Deep nested permission resolution across multiple resource types. |
| 69 | + |
| 70 | +- **Scenario**: `repository:backend-api` → `organization:acme-corp` → `group:engineering` → `user:alice` |
| 71 | +- **Features**: 3-level nesting, mixed permission types, hierarchical visualization |
| 72 | + |
| 73 | +### Example 7: Bulk Mixed Results 📊 |
| 74 | + |
| 75 | +**File**: `example7_bulk_mixed_results.html` |
| 76 | + |
| 77 | +Multiple permission checks with different outcomes in one report. |
| 78 | + |
| 79 | +- **Checks**: 3 checks (✓ has permission, ⨉ no permission, ? missing context) |
| 80 | +- **Features**: Visual separators, check numbering, shared metadata header |
| 81 | + |
| 82 | +--- |
| 83 | + |
| 84 | +## 🎨 Visual Features |
| 85 | + |
| 86 | +### Icons & Color Coding |
| 87 | + |
| 88 | +| Icon | Meaning | Color | CSS Class | |
| 89 | +|------|---------|-------|-----------| |
| 90 | +| ✓ | Has Permission | Green (#4ec9b0) | `.icon.has-permission` | |
| 91 | +| ⨉ | No Permission | Red (#f48771) | `.icon.no-permission` | |
| 92 | +| ? | Conditional/Missing Context | Purple (#c586c0) | `.icon.conditional` | |
| 93 | +| ! | Cycle Detected | Orange (#ce9178) | `.icon.cycle` | |
| 94 | +| ∵ | Unspecified | Yellow (#dcdcaa) | `.icon.unspecified` | |
| 95 | + |
| 96 | +### Permission Types |
| 97 | + |
| 98 | +- **Permissions** (green): `view`, `edit`, `admin`, `push` |
| 99 | +- **Relations** (orange): `member`, `viewer`, `owner` |
| 100 | + |
| 101 | +### Badges |
| 102 | + |
| 103 | +- **cached by spicedb** (blue) - Result from SpiceDB dispatch cache |
| 104 | +- **cached by materialize** (purple) - Result from materialized view |
| 105 | +- **cycle** (orange) - Circular dependency detected |
| 106 | + |
| 107 | +--- |
| 108 | + |
| 109 | +## 🌓 Dark/Light Mode |
| 110 | + |
| 111 | +All examples support **automatic theme switching** based on your system preference: |
| 112 | + |
| 113 | +- **Dark Mode** (default): VS Code Dark+ theme |
| 114 | +- **Light Mode**: High-contrast light theme for printing |
| 115 | + |
| 116 | +Change your system theme and refresh the page to see the difference! |
| 117 | + |
| 118 | +--- |
| 119 | + |
| 120 | +## 🧪 Interactive Features |
| 121 | + |
| 122 | +### Click to Expand/Collapse |
| 123 | + |
| 124 | +- Click any **▶** arrow to expand nested traces |
| 125 | +- Click again (or **▼**) to collapse |
| 126 | +- All nodes open by default for easy viewing |
| 127 | +- Smooth rotation animation |
| 128 | + |
| 129 | +### Hover Effects |
| 130 | + |
| 131 | +- Nodes subtly highlight on hover |
| 132 | +- Smooth 0.2s transitions |
| 133 | +- Cursor changes to pointer on interactive elements |
| 134 | + |
| 135 | +### Keyboard Navigation |
| 136 | + |
| 137 | +- **Tab** through interactive elements |
| 138 | +- **Enter/Space** to expand/collapse |
| 139 | +- **ARIA labels** for screen readers |
| 140 | +- Full keyboard accessibility |
| 141 | + |
| 142 | +--- |
| 143 | + |
| 144 | +## 📐 Technical Details |
| 145 | + |
| 146 | +### Architecture |
| 147 | + |
| 148 | +- **Zero dependencies**: Self-contained HTML files |
| 149 | +- **No JavaScript**: Pure HTML/CSS using native `<details>` elements |
| 150 | +- **Embedded CSS**: ~5KB stylesheet included inline |
| 151 | +- **File sizes**: 6.9KB - 7.9KB per trace |
| 152 | + |
| 153 | +### Performance |
| 154 | + |
| 155 | +- **Render time**: <100ms for typical trace |
| 156 | +- **Load time**: <50ms (no external resources) |
| 157 | +- **Memory**: ~512KB per renderer instance (pooled) |
| 158 | +- **Pre-allocation**: 8KB capacity hint per trace, 1MB cap for bulk operations |
| 159 | + |
| 160 | +### Security |
| 161 | + |
| 162 | +- **XSS protection**: All user strings escaped with `html.EscapeString()` |
| 163 | +- **DoS protection**: Metadata capped at 1024 runes, recursion limited to 100 levels |
| 164 | +- **UTF-8 safe**: Rune-aware truncation prevents boundary panics |
| 165 | + |
| 166 | +### Accessibility |
| 167 | + |
| 168 | +- **Semantic HTML5**: Proper use of `<details>`, `<summary>`, `<code>` tags |
| 169 | +- **ARIA labels**: Descriptive labels on all interactive elements |
| 170 | +- **Keyboard navigable**: Tab, Enter, Space all work as expected |
| 171 | +- **Screen reader friendly**: Proper heading hierarchy and roles |
| 172 | + |
| 173 | +### Browser Support |
| 174 | + |
| 175 | +- Chrome/Edge 90+ ✅ |
| 176 | +- Firefox 88+ ✅ |
| 177 | +- Safari 14+ ✅ |
| 178 | +- All modern browsers with `<details>` element support (2020+) |
| 179 | + |
| 180 | +--- |
| 181 | + |
| 182 | +## 🚀 Generating Your Own |
| 183 | + |
| 184 | +### Single Trace |
| 185 | + |
| 186 | +```bash |
| 187 | +zed permission check document:report-2024 view user:alice \ |
| 188 | + --explain \ |
| 189 | + --output=trace.html |
| 190 | +``` |
| 191 | + |
| 192 | +### Bulk Checks |
| 193 | + |
| 194 | +```bash |
| 195 | +zed permission check-bulk --explain --output=bulk.html < checks.jsonl |
| 196 | +``` |
| 197 | + |
| 198 | +### With Custom Metadata |
| 199 | + |
| 200 | +```bash |
| 201 | +zed permission check document:doc1 view user:alice \ |
| 202 | + --explain \ |
| 203 | + --output=trace.html \ |
| 204 | + --server=grpc.authzed.com:443 \ |
| 205 | + --version=v1.35.0 |
| 206 | +``` |
| 207 | + |
| 208 | +--- |
| 209 | + |
| 210 | +## 🔍 Implementation Details |
| 211 | + |
| 212 | +### Caveat Evaluation |
| 213 | + |
| 214 | +- **Expression display**: CEL expressions shown in italic |
| 215 | +- **Caveat name**: Purple bold text |
| 216 | +- **Context**: Pretty-printed JSON in monospace font |
| 217 | +- **Result indicators**: ✓ (true), ⨉ (false), ? (missing context) |
| 218 | + |
| 219 | +### Bulk Check Support |
| 220 | + |
| 221 | +- **Visual separators**: 2px solid line between checks with 30px margin |
| 222 | +- **Check numbering**: "Check #1", "Check #2", etc. |
| 223 | +- **Shared metadata**: Single header for all checks (efficient rendering) |
| 224 | + |
| 225 | +### Tree Structure |
| 226 | + |
| 227 | +- **Expandable nodes**: `<details>` with `<summary>` for interaction |
| 228 | +- **Leaf nodes**: Simple `<div>` (end of permission chain) |
| 229 | +- **Indentation**: Visual hierarchy with connecting lines |
| 230 | +- **Gap spacing**: 8px between elements for readability |
| 231 | + |
| 232 | +### Theme Colors (Dark Mode) |
| 233 | + |
| 234 | +```css |
| 235 | +--bg-primary: #1e1e1e /* Body background */ |
| 236 | +--bg-secondary: #252526 /* Tree container */ |
| 237 | +--bg-tertiary: #2d2d30 /* Header, hover states */ |
| 238 | +--text-primary: #d4d4d4 /* Main text */ |
| 239 | +--text-faint: #858585 /* Dimmed text */ |
| 240 | +--success: #4ec9b0 /* Has permission */ |
| 241 | +--error: #f48771 /* No permission */ |
| 242 | +--conditional: #c586c0 /* Missing context */ |
| 243 | +--cycle: #ce9178 /* Cycles */ |
| 244 | +``` |
| 245 | + |
| 246 | +--- |
| 247 | + |
| 248 | +## 🧪 Testing Coverage |
| 249 | + |
| 250 | +All examples are validated with comprehensive test coverage: |
| 251 | + |
| 252 | +- ✅ Has permission rendering |
| 253 | +- ✅ No permission rendering |
| 254 | +- ✅ Conditional permission with caveat |
| 255 | +- ✅ Missing context handling |
| 256 | +- ✅ Cycle detection |
| 257 | +- ✅ Bulk check rendering (1000+ traces) |
| 258 | +- ✅ XSS protection (script tag injection) |
| 259 | +- ✅ UTF-8 truncation safety |
| 260 | +- ✅ Pool lifecycle (no memory leaks) |
| 261 | +- ✅ Metadata rendering |
| 262 | +- ✅ Subject with relation |
| 263 | +- ✅ Nil resource handling |
| 264 | +- ✅ Deep nesting (100 levels) |
| 265 | + |
| 266 | +--- |
| 267 | + |
| 268 | +## 🎯 Use Cases |
| 269 | + |
| 270 | +1. **Debugging**: Understand why a permission check failed or succeeded |
| 271 | +2. **Documentation**: Share permission resolution details with your team |
| 272 | +3. **Audit Trails**: Save HTML reports for compliance and security audits |
| 273 | +4. **Testing**: Visual regression testing for permission logic changes |
| 274 | +5. **Education**: Teach SpiceDB concepts with interactive visual examples |
| 275 | +6. **Demos**: Beautiful examples for presentations and blog posts |
| 276 | + |
| 277 | +--- |
| 278 | + |
| 279 | +## 🎁 Bonus Features |
| 280 | + |
| 281 | +### Copy-Paste Friendly |
| 282 | + |
| 283 | +- Self-contained HTML files (no external dependencies) |
| 284 | +- Can be emailed or shared directly |
| 285 | +- Work offline |
| 286 | + |
| 287 | +### Print Support |
| 288 | + |
| 289 | +- Automatically switches to light theme for printing |
| 290 | +- Clear black/white output |
| 291 | +- No background colors to waste ink |
| 292 | + |
| 293 | +### Mobile Responsive |
| 294 | + |
| 295 | +- Viewport meta tag for proper scaling |
| 296 | +- Flexible layout adapts to screen size |
| 297 | +- Touch-friendly expand/collapse |
| 298 | + |
| 299 | +### No JavaScript Required |
| 300 | + |
| 301 | +- Native `<details>` elements for expand/collapse |
| 302 | +- Pure CSS animations |
| 303 | +- Works even with JavaScript disabled |
| 304 | + |
| 305 | +--- |
| 306 | + |
| 307 | +## 📖 Legend |
| 308 | + |
| 309 | +Each HTML file includes an interactive legend at the bottom explaining: |
| 310 | + |
| 311 | +- Icon meanings (✓ ⨉ ? ! ∵) |
| 312 | +- Color coding (permissions vs relations) |
| 313 | +- Badge types (cache, cycle) |
| 314 | + |
| 315 | +--- |
| 316 | + |
| 317 | +**Generated by**: `zed` CLI tool |
| 318 | +**Renderer**: HTML trace visualizer with embedded CSS |
| 319 | +**Last Updated**: 2025-10-21 |
0 commit comments