Skip to content

Commit db0e06f

Browse files
committed
Improve README, lint
1 parent 213bab2 commit db0e06f

File tree

8 files changed

+242
-251
lines changed

8 files changed

+242
-251
lines changed

README.md

Lines changed: 57 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,99 +1,90 @@
1-
# gitMDM: The MDM that isn't
1+
# gitMDM
22

3-
![gitMDM Logo](media/logo_small.png)
3+
Security-first compliance reporting that doesn't compromise your infrastructure.
44

5-
⚠️ **HIGHLY EXPERIMENTAL - MAY EAT YOUR CAT** ⚠️
5+
## The Problem
66

7-
## What
7+
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.
88

9-
A "Mobile Device Management" solution that stores compliance data in Git. Built to pass SOC 2 without requiring a highly privileged RCE
9+
## The Solution
1010

11-
## Why
11+
gitMDM proves compliance without compromising security:
12+
- **No arbitrary remote code execution** - Checks are compiled into the agent binary
13+
- **No privileged access** - Runs as a normal user
14+
- **No phone-home** - Your git repo, your endpoint, your control
15+
- **Works everywhere** - Including secure-by-default systems such as OpenBSD.
1216

13-
Because real MDMs are backdoors with compliance features. This just generates the reports auditors want without the ability to actually control your devices.
14-
15-
## Philosophy
16-
17-
- **Can't manage devices** - Only reports on them
18-
- **Can't execute commands** - Read-only by design
19-
- **Can't phone home** - Your Git repo, your control
20-
- **Can't compromise systems** - No privileges, no access
21-
22-
## Architecture
17+
## How It Works
2318

2419
```
25-
Device → Agent (reads) → Server (receives) → Git (stores) → Auditor ✅
20+
[Agent] [Server] [Git]
21+
Run compiled checks → Receive reports only → Immutable audit trail
2622
```
2723

28-
## Features
24+
The server **cannot** push commands. Ever. That's the point.
2925

30-
Proves compliance without control:
31-
- Disk encryption status
32-
- Firewall configuration
33-
- User accounts
34-
- System updates
35-
- Screensaver locks
26+
## Quick Start
3627

37-
## Cross Platform
28+
```bash
29+
# Server
30+
./gitmdm-server -git [email protected]:org/compliance.git -api-key SECRET
3831

39-
We currently support:
32+
# Agent (checks compiled in from checks.yaml)
33+
./gitmdm-agent -server https://server:8080
34+
```
4035

41-
* Linux
42-
* macOS
43-
* FreeBSD
44-
* OpenBSD
45-
* NetBSD
46-
* DragonFlyBSD
47-
* Solaris
48-
* illumos
49-
* Windows 11
36+
## What You Get
5037

51-
gitMDM supports any architecture supported by the Go programming language: from riscv to ppc64.
38+
SOC 2 compliance evidence in git:
39+
```
40+
devices/laptop-alice/disk_encryption.json ✓
41+
devices/laptop-alice/screen_lock.json ✓
42+
devices/server-prod/firewall.json ✓
43+
```
5244

53-
## Installation
45+
Every check, every change, cryptographically signed and timestamped.
5446

55-
```bash
56-
# Build
57-
make build
47+
## Supported Platforms
5848

59-
# Server (pick one)
60-
./gitmdm-server -git https://github.com/you/compliance.git # Clone & push
61-
./gitmdm-server -clone /path/to/repo # Use existing
49+
Linux, macOS, Windows, FreeBSD, OpenBSD, NetBSD, DragonFlyBSD, Solaris, illumos
6250

63-
# Agent
64-
./gitmdm-agent -server http://your-server:8080
51+
## checks.yaml
6552

66-
# Deploy
67-
echo "gitmdm-agent -server http://your-server:8080" | crontab -
53+
```yaml
54+
checks:
55+
disk_encryption:
56+
openbsd: "bioctl softraid0 | grep -q CRYPTO"
57+
linux: "lsblk -o NAME,FSTYPE | grep -q crypto_LUKS"
58+
darwin: "fdesetup status | grep -q 'On'"
6859
```
6960
70-
## GitHub Auth
71-
72-
```bash
73-
# Use SSH (recommended)
74-
./gitmdm-server -git [email protected]:you/compliance.git
61+
Edit, compile, deploy. No runtime configuration files to tamper with.
7562
76-
# Or GitHub CLI
77-
gh auth setup-git
78-
```
63+
## Security Guarantees
7964
80-
## Configuration
65+
- Server compromise = read-only access to compliance reports
66+
- No arbitrary code execution, even with root on the server
67+
- Agent decides what runs based on compiled-in checks
68+
- Bash restricted mode when shell execution is needed
8169
82-
Edit `checks.yaml` to define compliance checks. Default config satisfies most auditors.
70+
## Building
8371
84-
## Security
85-
86-
Traditional MDMs: Give someone your house keys to check if the door is locked.
87-
gitMDM: Someone photographs your locked door from across the street.
72+
```bash
73+
vim checks.yaml # Define your compliance checks
74+
make build # Compiles checks into binary
75+
```
8876

89-
**Result**: Compliance without compromise.
77+
## FAQ
9078

91-
**Note**: The server accepts reports without authentication by default. While this means anyone could submit false compliance data, they still can't access or control your actual devices. Enable API key authentication (`-api-key`) or use network-level controls if you need to verify report sources.
79+
**Q: Is this SOC 2 compliant?**
80+
A: It generates the reports auditors need. Without the backdoors.
9281

93-
## Disclaimer
82+
**Q: What if we need to change checks?**
83+
A: Rebuild and redeploy. Immutability is a feature.
9484

95-
This software proves compliance. It doesn't actually manage devices. That's the point.
85+
**Q: Why git?**
86+
A: Cryptographic proof, audit trail, existing tooling, no database.
9687

9788
---
9889

99-
*Built with spite by someone who wanted to pass SOC 2 with OpenBSD.*
90+
*Built for organizations that refuse to compromise security for compliance.*

cmd/agent/executeCommand.go

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,19 @@ import (
55
"context"
66
"errors"
77
"fmt"
8+
"gitmdm/internal/gitmdm"
89
"log"
910
"os/exec"
1011
"strings"
1112
"time"
12-
13-
"gitmdm/internal/types"
1413
)
1514

1615
// executeCommandWithPipes executes a command and captures stdout/stderr separately.
1716
// SECURITY: Commands come from checks.yaml which must be controlled by the system admin.
1817
// Bash restricted mode (-r) prevents: cd, PATH changes, output redirection, running programs
1918
// with / in name. Complex shell operations (pipes, grep, awk) are still allowed by design
2019
// as they're needed for compliance checks. The agent runs with user privileges only.
21-
func (*Agent) executeCommandWithPipes(ctx context.Context, checkName, command string) types.Check {
20+
func (*Agent) executeCommandWithPipes(ctx context.Context, checkName, command string) gitmdm.Check {
2221
start := time.Now()
2322
ctx, cancel := context.WithTimeout(ctx, commandTimeout)
2423
defer cancel()
@@ -44,8 +43,17 @@ func (*Agent) executeCommandWithPipes(ctx context.Context, checkName, command st
4443
duration := time.Since(start)
4544

4645
// Limit output sizes
47-
stdout := limitOutput(stdoutBuf.Bytes(), maxOutputSize)
48-
stderr := limitOutput(stderrBuf.Bytes(), maxOutputSize)
46+
stdoutBytes := stdoutBuf.Bytes()
47+
stdout := string(stdoutBytes)
48+
if len(stdoutBytes) > maxOutputSize {
49+
stdout = string(stdoutBytes[:maxOutputSize]) + "\n[Output truncated to 10KB]..."
50+
}
51+
52+
stderrBytes := stderrBuf.Bytes()
53+
stderr := string(stderrBytes)
54+
if len(stderrBytes) > maxOutputSize {
55+
stderr = string(stderrBytes[:maxOutputSize]) + "\n[Output truncated to 10KB]..."
56+
}
4957

5058
// Determine exit code
5159
exitCode := 0
@@ -92,19 +100,10 @@ func (*Agent) executeCommandWithPipes(ctx context.Context, checkName, command st
92100
duration, exitCode, len(stdout), len(stderr), command)
93101
}
94102

95-
return types.Check{
103+
return gitmdm.Check{
96104
Command: command,
97105
Stdout: stdout,
98106
Stderr: stderr,
99107
ExitCode: exitCode,
100108
}
101109
}
102-
103-
// limitOutput truncates output if it exceeds maxSize.
104-
func limitOutput(data []byte, maxSize int) string {
105-
if len(data) > maxSize {
106-
truncated := data[:maxSize]
107-
return string(truncated) + "\n[Output truncated to 10KB]..."
108-
}
109-
return string(data)
110-
}

0 commit comments

Comments
 (0)