@@ -1,2 +1,119 @@
|
||||
# sessiongurad
|
||||
# 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
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user