Files
sessiongurad/README.md
jbergner 1d8e36c53a
Some checks failed
release-tag / release-image (push) Has been cancelled
Init
2026-08-22 08:10:11 +02:00

120 lines
5.2 KiB
Markdown

# SessionGuard
SessionGuard is a Go-based management layer for Windows Remote Desktop Session Hosts. It is intended for environments that use Guacamole or another access gateway and want a small subset of the operational features commonly provided by Citrix management/profile components.
## Implemented MVP
- Windows service agent
- RDS/WTS session inventory
- delayed profile deletion after a real session disappears
- safety exclusions, allowed profile roots, retries, and dry-run mode
- per-user template enforcement for files, directories, `.url` links and `.lnk` shortcuts
- server basics: hostname, Windows version/build, uptime, RAM
- local agent dashboard
- Linux/Docker master dashboard for all agents
- outbound agent-to-master heartbeats
- bootstrap enrollment followed by per-agent bearer credentials
- per-agent policies and "apply to all agents"
- Pocket ID / generic OIDC authentication for master and local agent UI
- last-known policy continues to work if the master is unavailable
## Important safety note
Profile deletion is destructive. Start with `dry_run: true`, verify exclusions and `allowed_profile_roots`, test on a non-production RDS host, and only then disable dry-run. SessionGuard calls the Windows user-profile deletion API; it does not recursively delete arbitrary profile paths itself.
## Build
Requirements: Go 1.23+ and Internet access for the Go modules on the first build.
```powershell
.\scripts\build.ps1
```
Or:
```bash
GOOS=windows GOARCH=amd64 CGO_ENABLED=0 go build -o sessionguard-agent.exe ./cmd/agent
go build -o sessionguard-master ./cmd/master
```
## Master deployment
1. Copy `configs/master.example.json` to `deploy/master.json` and edit it.
2. In Pocket ID create an OIDC client whose callback URL is `https://sessionguard.example.org/oidc/callback`.
3. Restrict the Pocket ID client to the intended admin group and configure the same group in `admin_groups`.
4. Put a TLS reverse proxy in front of the master.
5. Start with `docker compose -f deploy/docker-compose.yml up -d --build`.
The container binds the example host port only to `127.0.0.1`; publish it through your reverse proxy rather than exposing plain HTTP.
## Agent deployment
1. Copy `configs/agent.example.json` to `configs/agent.json` and edit the master URL, enrollment token and OIDC settings.
2. Create a Pocket ID OIDC client for the agent's management URL, for example `https://ts01-mgmt.example.org/oidc/callback`.
3. Build the Windows agent.
4. Run `scripts/install-agent.ps1` from an elevated PowerShell prompt.
5. Keep `dry_run: true` until profile cleanup has been observed successfully.
The service is installed as LocalSystem by default. If a template `source` points to a UNC share, grant read access to the server computer account (`DOMAIN\SERVER$`) or change the service identity to an appropriate gMSA/service account. Do not put share passwords in the SessionGuard JSON configuration.
## Example templates
```json
[
{
"id": "support",
"kind": "url",
"target": "Desktop\\Support.url",
"url": "https://support.example.org",
"overwrite": true
},
{
"id": "erp",
"kind": "shortcut",
"target": "Desktop\\ERP.lnk",
"overwrite": true,
"shortcut": {
"target": "C:\\Program Files\\ERP\\erp.exe",
"arguments": "--terminal"
}
},
{
"id": "defaults",
"kind": "file",
"target": "AppData\\Roaming\\Example\\defaults.json",
"source": "\\\\fileserver\\templates\\defaults.json",
"overwrite": true
}
]
```
All `target` values are relative to the user's profile. Attempts to escape the profile root are rejected.
## Local management during a master outage
The Windows agent continues cleanup and template work using its persisted policy. Its local web UI remains available independently of the master, provided Pocket ID is reachable. A locally saved emergency policy remains in effect until the master reconnects; if the master already has a different desired policy for that agent, the master policy is then reapplied.
## Pocket ID notes
SessionGuard requests the `openid`, `profile`, `email` and `groups` scopes. Use `admin_groups` as a second authorization check in addition to Pocket ID's client-side allowed-group restriction. The master and agent should be served over HTTPS and `secure_cookie` should remain enabled.
## What is intentionally not implemented yet
Full Citrix-style profile roaming/restoration is not part of v0.1. Copying an entire profile, especially `NTUSER.DAT` and registry-backed settings, after Windows has loaded that profile is unsafe. See `docs/ARCHITECTURE.md` for the recommended extension path.
## Repository layout
```text
cmd/master Linux/Docker master binary
cmd/agent Windows service binary
internal/agent agent lifecycle, cleanup, heartbeat, local UI
internal/master enrollment, dashboard, policy distribution
internal/windowsx WTS, profile and Windows server APIs
internal/templates template comparison/application
internal/auth Pocket ID / OIDC login
configs example JSON configurations
deploy Docker Compose example
scripts build/install helpers
docs architecture notes
```