|
1 | | -# gitMDM |
| 1 | +# gitMDM 🧪 |
2 | 2 |
|
3 | | -Security-first compliance reporting that doesn't compromise your infrastructure. |
| 3 | +The MDM for startups that actually care about security. |
4 | 4 |
|
5 | | - |
| 5 | +## Your Problem |
6 | 6 |
|
7 | | -## The Problem |
| 7 | +Your startup just hit the enterprise sales milestone where someone asks "are you SOC 2 compliant?" Meanwhile, your engineering team runs OpenBSD on ThinkPads, Arch on Frameworks, and that one person still dailying Plan 9. |
8 | 8 |
|
9 | | -Every MDM is a backdoor. They typically require root access and arbitrary remote code execution. They're incompatible with secure-by-default operating systems. Yet auditors require them for SOC 2. |
| 9 | +Traditional MDMs want root access, auto-update themselves from the internet, and can execute arbitrary code pushed from their cloud. Your security engineer just had an aneurysm. |
10 | 10 |
|
11 | | -## The Solution |
| 11 | +## Our Solution |
12 | 12 |
|
13 | | -gitMDM proves compliance without compromising security: |
14 | | -- **No arbitrary remote code execution** - Checks are compiled into the agent binary |
15 | | -- **No privileged access** - Runs as a normal user |
16 | | -- **No phone-home** - Your git repo, your endpoint, your control |
17 | | -- **Works everywhere** - Including secure-by-default systems such as OpenBSD. |
| 13 | +gitMDM proves compliance without the backdoor: |
18 | 14 |
|
19 | | -## Screenshots |
20 | | - |
21 | | -### Device List |
22 | | -<a href="media/dashboard.png"><img src="media/dashboard.png" alt="Dashboard" width="400"/></a> |
23 | | - |
24 | | -### Device Details |
25 | | - |
26 | | -<a href="media/report.png"><img src="media/report.png" alt="Agent Report" width="400"/></a> |
27 | | - |
28 | | -### Remediation |
29 | | -<a href="media/remediate.png"><img src="media/remediate.png" alt="Remediation Steps" width="400"/></a> |
30 | | - |
31 | | -## How It Works |
32 | | - |
33 | | -``` |
34 | | -[Agent] [Server] [Git] |
35 | | -Run compiled checks → Receive reports only → Tamper-resistant audit trail |
36 | 15 | ``` |
| 16 | +Traditional MDM: "Install our kernel extension!" |
| 17 | +Your Team: "How about no." |
37 | 18 |
|
38 | | -The server **cannot** push commands. Ever. That's the point. |
| 19 | +gitMDM: "Run a read-only agent that reports to YOUR server" |
| 20 | +Your Team: "...continue" |
| 21 | +``` |
39 | 22 |
|
40 | | -## Quick Start |
| 23 | +### Why Your Security Team Will Actually Approve This |
41 | 24 |
|
42 | | -```bash |
43 | | -# Server - now with 100% less git CLI dependency! |
44 | | -# Auto-generates a join key from hardware ID if you're too lazy to set one |
45 | | -./gitmdm-server -git /path/to/compliance # Creates repo if it doesn't exist |
46 | | -# or |
47 | | -./gitmdm-server -clone /existing/repo # Uses existing local repo |
48 | | - |
49 | | -# The server will display something like: |
50 | | -# ═══════════════════════════════════════════════════════════════ |
51 | | -# GitMDM Server Started |
52 | | -# Join Key: 926DD23A5B |
53 | | -# |
54 | | -# To register an agent, run: |
55 | | -# ./gitmdm-agent --server http://localhost:8080 --join 926DD23A5B |
56 | | -# ═══════════════════════════════════════════════════════════════ |
57 | | - |
58 | | -# Agent - checks in every 20 minutes (because 5 was too clingy) |
59 | | -./gitmdm-agent --server http://localhost:8080 --join 926DD23A5B |
60 | | -``` |
| 25 | +- **Zero Remote Execution**: Can't push commands. Not won't. Can't. The server only receives data. |
| 26 | +- **No Auto-Updates**: Agent is a static binary. Updates require YOU to rebuild and redeploy. |
| 27 | +- **Runs as User**: No root, no SYSTEM. Just a regular user process. |
| 28 | +- **You Own Everything**: Your server, your git repo, your data. Host it in your VPC. |
| 29 | +- **Audit Everything**: Every change is a git commit. `git blame` for compliance. |
61 | 30 |
|
62 | | -### Environment Variables (for the Docker crowd) |
| 31 | +## Quick Start for the Impatient |
63 | 32 |
|
64 | 33 | ```bash |
65 | | -# Server accepts these if you're allergic to flags |
66 | | -export GIT_REPO=git@github.com:org/compliance.git |
67 | | -export PORT=8080 |
68 | | -export JOIN_KEY=SUPERSECRET123 # Or let it auto-generate one |
69 | | -./gitmdm-server |
70 | | -``` |
| 34 | +# On your secure server (or laptop, we don't judge) |
| 35 | +./gitmdm-server -git /opt/compliance |
71 | 36 |
|
72 | | -## Local Checks |
| 37 | +# On your OpenBSD machine |
| 38 | +$ doas pkg_add gitmdm-agent # just kidding, compile it yourself |
| 39 | +$ ./gitmdm-agent --install --server https://comply.internal --join XXXX |
73 | 40 |
|
74 | | -You can run the compliance checks even without a server: |
| 41 | +# On your Linux laptop |
| 42 | +$ ./gitmdm-agent --install --server https://comply.internal --join XXXX |
75 | 43 |
|
76 | | -```bash |
77 | | -./out/gitmdm-agent -run all |
| 44 | +# On that Mac the designer insisted on |
| 45 | +$ ./gitmdm-agent --install --server https://comply.internal --join XXXX |
78 | 46 | ``` |
79 | 47 |
|
80 | | -You'll see output similar to: |
| 48 | +Join keys stored in `~/.config/gitmdm/` (or wherever your OS says), not in process lists. |
81 | 49 |
|
82 | | -```log |
83 | | -🔍 Running security checks... |
| 50 | +## What SOC 2 Actually Requires vs What We Check |
84 | 51 |
|
85 | | -⚠️ 3 issues require attention |
| 52 | +| SOC 2 Says | Traditional MDMs Do | We Do | |
| 53 | +|------------|---------------------|--------| |
| 54 | +| Disk encryption | Run as root, phone home for instructions | Read `/proc/mounts` as user | |
| 55 | +| Screen locks | Auto-update from vendor's CDN | Check your screensaver config | |
| 56 | +| OS updates | Force reboots during demos | Report version numbers | |
| 57 | +| Firewall enabled | Execute arbitrary scripts from cloud | Check `iptables -L` output | |
86 | 58 |
|
87 | | -🔸 screen lock |
88 | | - 🐞 Problem: Screen idle time too long (1 hour, SOC 2 requires ≤15 min); Screen lock delay too long (4 hours, SOC 2 requires ≤15 min) |
89 | | - 💻 Evidence: defaults -currentHost read com.apple.screensaver idleTime && sysadminctl -screenLock status |
| 59 | +## Platform Detection That Actually Works |
90 | 60 |
|
91 | | - 🔧 How to fix: |
92 | | - 1. Open System Settings > Lock Screen |
93 | | - 2. Set 'Start Screen Saver when inactive' to 15 minutes or less |
94 | | - 3. Open System Settings > Lock Screen |
95 | | - 4. Set 'Require password after screen saver begins' to 'immediately' |
| 61 | +```yaml |
| 62 | +# Your snowflake setups, our problem: |
| 63 | +- MATE on OpenBSD (we see you) |
| 64 | +- Sway on Alpine (of course) |
| 65 | +- i3 on Debian (classic) |
| 66 | +- Whatever that custom Wayland compositor you wrote is |
| 67 | +- Even macOS (unfortunate, but supported) |
96 | 68 | ``` |
97 | 69 |
|
98 | | -## What You Get |
| 70 | +We detect 11+ desktop environments because your team refuses to standardize. |
| 71 | +
|
| 72 | +## Security Architecture |
99 | 73 |
|
100 | | -SOC 2 compliance evidence in git: |
101 | 74 | ``` |
102 | | -devices/ |
103 | | -├── 926DD23A5B/ # Hardware IDs, not names (privacy!) |
104 | | -│ ├── info.json # Device metadata |
105 | | -│ ├── disk_encryption.json ✓ |
106 | | -│ ├── screen_lock.json ✓ |
107 | | -│ └── firewall.json ✓ |
108 | | -└── README.md # Auto-created, unlike this one |
| 75 | +[Agent] [Server] [Git] |
| 76 | + | | | |
| 77 | + |-- HTTPS ------->| | |
| 78 | + | (reports) |--- git push -->| |
| 79 | + | | | |
| 80 | + X <-- CANNOT -----| | |
| 81 | + (execute) |
109 | 82 | ``` |
110 | 83 |
|
111 | | -Every check, every change, in git. No database to corrupt, no API to hack. |
112 | | - |
113 | | -## Supported Platforms |
| 84 | +The server literally cannot execute commands. We removed the code. It's not there. |
114 | 85 |
|
115 | | -Linux, macOS, Windows, FreeBSD, OpenBSD, NetBSD, DragonFlyBSD, Solaris, illumos |
| 86 | +## For Your Compliance Team |
116 | 87 |
|
117 | | -## checks.yaml |
| 88 | +"How do we prove compliance?" |
118 | 89 |
|
119 | | -```yaml |
120 | | -checks: |
121 | | - disk_encryption: |
122 | | - openbsd: "bioctl softraid0 | grep -q CRYPTO" |
123 | | - linux: "lsblk -o NAME,FSTYPE | grep -q crypto_LUKS" |
124 | | - darwin: "fdesetup status | grep -q 'On'" |
| 90 | +```bash |
| 91 | +$ cd compliance-repo |
| 92 | +$ git log --oneline |
| 93 | +8f3d2a1 workstation-42: disk encryption enabled |
| 94 | +7b2c3f9 laptop-dev-3: screen lock fixed |
| 95 | +5a1e8c4 desktop-1: firewall enabled |
125 | 96 | ``` |
126 | 97 |
|
127 | | -Edit, compile, deploy. No runtime configuration files to tamper with. |
| 98 | +"What if someone tampers with the agent?" |
| 99 | + |
| 100 | +They can. It's their machine. They can also lie on spreadsheets. At least this has timestamps. |
128 | 101 |
|
129 | | -## Security Guarantees |
| 102 | +"Is this enterprise-ready?" |
130 | 103 |
|
131 | | -- **Server compromise = read-only access to compliance reports** (and they're in git anyway) |
132 | | -- **No arbitrary code execution** - Not even with root on the server |
133 | | -- **Agent decides what runs** - Compiled-in checks, not runtime shenanigans |
134 | | -- **Bash restricted mode** - When we absolutely must shell out |
135 | | -- **No git CLI required** - Pure Go implementation (go-git), works in containers |
136 | | -- **Join key required** - Keeps the riffraff out of your compliance data |
| 104 | +No. But neither was Stripe when you started using it. |
137 | 105 |
|
138 | 106 | ## Building |
139 | 107 |
|
140 | 108 | ```bash |
141 | | -make all |
| 109 | +make all # Static binaries, because dynamic linking is attack surface |
142 | 110 | ``` |
143 | 111 |
|
144 | | -Compiles to static binaries because dynamic linking is for people who enjoy debugging production at 3 AM. |
| 112 | +No npm. No pip. No containers. Just Go. |
| 113 | + |
| 114 | +## Installation That Respects Your OS |
145 | 115 |
|
146 | | -## Code Philosophy |
| 116 | +- **Linux**: systemd user service (falls back to cron if you're systemd-free) |
| 117 | +- **OpenBSD**: cron (because rc.d requires root and we're not animals) |
| 118 | +- **macOS**: launchd (the least worst option) |
| 119 | +- **FreeBSD/NetBSD**: cron (see OpenBSD) |
147 | 120 |
|
148 | | -Written in Go, blessed by Rob Pike's simplicity principles: |
149 | | -- Functions read like recipes, not puzzle boxes |
150 | | -- No clever abstractions that require a PhD to understand |
151 | | -- Minimal dependencies (yaml, retry, go-git - that's it!) |
152 | | -- If a function is <7 lines and called once, it's inlined |
153 | | -- Security through simplicity, not complexity theater |
| 121 | +Pre-flight check ensures the server exists before installing. Novel concept. |
154 | 122 |
|
155 | | -## FAQ |
| 123 | +## FAQ for Security-Conscious Teams |
156 | 124 |
|
157 | | -**Q: Is this SOC 2 compliant?** |
158 | | -A: It generates the reports auditors need. Without the backdoors. |
| 125 | +**Q: Can this execute remote commands?** |
| 126 | +A: No. Check the code. The handler doesn't exist. |
159 | 127 |
|
160 | | -**Q: What if we need to change checks?** |
161 | | -A: Rebuild and redeploy. Immutability is a feature, not a bug. |
| 128 | +**Q: What about supply chain attacks?** |
| 129 | +A: It's 2 dependencies: yaml and retry. Vendor them if paranoid. |
162 | 130 |
|
163 | | -**Q: Why git?** |
164 | | -A: Cryptographic proof, audit trail, existing tooling, no database to "accidentally" DROP. |
| 131 | +**Q: Does it require root?** |
| 132 | +A: Never. User-level only. Your kernel remains unmolested. |
| 133 | + |
| 134 | +**Q: What data does it collect?** |
| 135 | +A: Read `checks.yaml`. It's compiled in. No surprises. |
| 136 | + |
| 137 | +**Q: Can we self-host?** |
| 138 | +A: That's the only option. There's no cloud service. You run it. |
| 139 | + |
| 140 | +**Q: What if an agent is compromised?** |
| 141 | +A: It can lie about that device's compliance. That's it. No lateral movement. |
| 142 | + |
| 143 | +**Q: OpenBSD pledge/unveil support?** |
| 144 | +A: On the roadmap. PRs welcome from fellow paranoids. |
| 145 | + |
| 146 | +--- |
165 | 147 |
|
166 | | -**Q: Does it need git installed?** |
167 | | -A: Nope! Uses go-git. Works in your hipster minimal container. |
| 148 | +*Built by engineers who rm -rf node_modules on principle.* |
168 | 149 |
|
169 | | -**Q: What's a join key?** |
170 | | -A: A speed bump for script kiddies. Not Fort Knox, but keeps honest people honest. |
| 150 | +**⚠️ EXPERIMENTAL** |
| 151 | +*But still more trustworthy than your current MDM.* |
171 | 152 |
|
172 | | -**Q: Why 20-minute check-ins?** |
173 | | -A: Because 5 minutes was needy, and daily was negligent. Goldilocks would approve. |
| 153 | +*Remember: Compliance theater is still theater, but at least our stage doesn't have backdoors.* |
174 | 154 |
|
175 | 155 | --- |
176 | 156 |
|
177 | | -*Built for organizations that refuse to compromise security for compliance.* |
| 157 | +*"Because your security posture shouldn't require the missionary position."* |
0 commit comments