# Security Posture Analysis: ops-jrz1 Dev Server ## Executive Summary ops-jrz1 is a shared development server for learning agentic coding. Current security posture is **acceptable for a trusted learning environment** but has gaps that should be addressed before onboarding untrusted users. ## Threat Model ### Assumed Users - **Learners**: Trusted individuals learning agentic coding - **Agentic Coders**: AI tools (Claude, opencode, etc.) running with user privileges ### Threat Actors 1. **Curious learner** - Explores beyond their sandbox (low intent, low skill) 2. **Compromised AI agent** - Prompt injection or malicious code execution 3. **Malicious insider** - Intentional abuse (not in scope for learning environment) ### Out of Scope - External attackers (network is properly firewalled) - Malicious insiders with intent to harm ## Current Security Controls ### ✅ Good | Control | Status | |---------|--------| | Firewall | Only 22, 80, 443 open | | Internal services | Bound to 127.0.0.1 only | | sudo access | Denied for learner users | | sops secrets | Root-only (/run/secrets) | | SSH auth | Key-only, no passwords | ### ⚠️ Gaps | Gap | Risk | Impact | |-----|------|--------| | Home dirs world-readable | Users can browse each other's code | Low - learning env | | Shared Slack tokens | All users share one bot identity | Medium - actions attributed to same bot | | Unrestricted egress | Users/agents can reach any network | Medium - data exfil possible | | No resource limits | One user can exhaust CPU/RAM/disk | Medium - DoS other users | | Agentic coder privileges | AI runs with full user permissions | Medium - same as human user | ## Asset Inventory ### Secrets at Risk | Secret | Location | Access | Risk | |--------|----------|--------|------| | Slack bot token | /etc/slack-learner.env | learners group | Low - shared intentionally | | Slack app token | /etc/slack-learner.env | learners group | Low - shared intentionally | | Matrix registration | /run/secrets | root only | Protected | | Maubot credentials | /run/secrets | root only | Protected | | User SSH keys | ~/.ssh | user only | Protected | | User AI auth tokens | ~/.config/* | user only | User responsibility | ### Services | Service | Port | Exposure | Notes | |---------|------|----------|-------| | SSH | 22 | Public | Key auth only | | nginx | 80/443 | Public | Reverse proxy | | PostgreSQL | 5432 | localhost | Unix socket preferred | | Conduwuit | 8008 | localhost | Matrix homeserver | | Forgejo | 3000 | localhost | Git repos | | mautrix-slack | 29319 | localhost | Bridge | | maubot | 29316 | localhost | Bot framework | ## Risk Assessment ### What can a compromised user/agent do? 1. **Read other users' code** - Home dirs are world-readable 2. **Use shared Slack bot** - Post messages as the shared bot 3. **Exhaust resources** - No cgroups/quotas 4. **Exfiltrate data** - Unrestricted network egress 5. **Install malware** - In their own profile, persists across sessions ### What can they NOT do? 1. ❌ Read /run/secrets 2. ❌ sudo/become root 3. ❌ Access other users' SSH keys 4. ❌ Modify system configuration 5. ❌ Access PostgreSQL directly (unless through app) ## Recommendations ### Priority 1 (Do Now) - [ ] **Make home dirs private** - `chmod 700 /home/*` - [ ] **Document shared Slack token risk** - Users know bot is shared ### Priority 2 (Before More Users) - [ ] **Add resource limits** - cgroups for CPU/memory per user - [ ] **Disk quotas** - Prevent one user filling disk - [ ] **Consider per-user Slack apps** - If attribution matters ### Priority 3 (Hardening) - [ ] **Network egress filtering** - Allowlist or log outbound - [ ] **Audit logging** - Track user commands (auditd) - [ ] **Separate AI auth storage** - Investigate ~/.config isolation ### Not Recommended - ❌ Full sandboxing (VMs, containers per user) - Overkill for learning - ❌ Restricting nix profile install - Breaks user autonomy ## Conclusion For a **trusted learning environment**, current posture is acceptable with minor fixes (home dir permissions). Before scaling to untrusted users, implement Priority 2 controls. --- *Generated: 2026-01-03* *Issue: ops-jrz1-k2a*