feat: Fleet Forge UEM - device management, agent, remote desktop (VNC), TLS reverse proxy
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
# ADR-001: Monorepo with pnpm Workspaces
|
||||
|
||||
## Status
|
||||
Accepted
|
||||
|
||||
## Context
|
||||
Fleet Forge requires multiple packages: API server, web dashboard, shared types, and the Go agent. We need a structure that supports shared code, independent builds, and a single repository.
|
||||
|
||||
## Decision
|
||||
Use pnpm workspaces for the TypeScript/Node.js packages. The Go agent lives in the same repo but is built independently.
|
||||
|
||||
## Rationale
|
||||
- pnpm workspaces provide efficient dependency management with a single lockfile
|
||||
- Workspace references (`workspace:*`) enable local development without publishing
|
||||
- Compatible with Next.js, Express, and Drizzle ORM
|
||||
- The Go agent uses standard Go modules independently
|
||||
|
||||
## Consequences
|
||||
- All TS packages share a common `tsconfig.base.json`
|
||||
- Build order is managed via workspace dependency graph
|
||||
- Go agent has its own `go.mod` and is not part of the pnpm workspace
|
||||
@@ -0,0 +1,22 @@
|
||||
# ADR-002: TypeScript + Express for API
|
||||
|
||||
## Status
|
||||
Accepted
|
||||
|
||||
## Context
|
||||
The API server needs to be fast to develop, type-safe, and maintainable.
|
||||
|
||||
## Decision
|
||||
Use TypeScript with Express.js, Drizzle ORM, and PostgreSQL.
|
||||
|
||||
## Rationale
|
||||
- TypeScript provides end-to-end type safety when shared with the frontend
|
||||
- Express is mature, well-documented, and sufficient for a REST API
|
||||
- Drizzle ORM is lightweight, type-safe, and generates SQL directly
|
||||
- Zod provides runtime request validation that aligns with TypeScript types
|
||||
- bcrypt for password hashing, JWT for auth tokens
|
||||
|
||||
## Consequences
|
||||
- API and web share the `@fleetforge/shared` package
|
||||
- Drizzle migrations are SQL-based, version-controlled in `infrastructure/migrations/`
|
||||
- No ORM overhead from heavier alternatives (Prisma, TypeORM)
|
||||
@@ -0,0 +1,22 @@
|
||||
# ADR-003: Go for Forge Agent
|
||||
|
||||
## Status
|
||||
Accepted
|
||||
|
||||
## Context
|
||||
The agent needs to run on Linux, Windows, and macOS with minimal dependencies and resource usage.
|
||||
|
||||
## Decision
|
||||
Write the agent in Go, producing statically-linked binaries for each platform.
|
||||
|
||||
## Rationale
|
||||
- Go compiles to a single binary with no runtime dependencies
|
||||
- Excellent cross-compilation support (GOOS/GOARCH)
|
||||
- Small memory footprint suitable for resource-constrained devices
|
||||
- gopsutil library provides cross-platform system metrics
|
||||
- Strong standard library for HTTP, JSON, and OS interaction
|
||||
|
||||
## Consequences
|
||||
- Agent is built separately from the TypeScript monorepo
|
||||
- Agent version is tracked in the source code and reported in heartbeats
|
||||
- Future: could use Go plugins for platform-specific adapters
|
||||
@@ -0,0 +1,24 @@
|
||||
# ADR-004: Authentication Model
|
||||
|
||||
## Status
|
||||
Accepted
|
||||
|
||||
## Context
|
||||
The platform needs secure authentication for both admin users and device agents.
|
||||
|
||||
## Decision
|
||||
- **Admin users**: JWT-based authentication with bcrypt password hashes
|
||||
- **Device agents**: Unique credential per device, stored as SHA-256 hashes in the database
|
||||
- **Enrollment**: Time-limited, optionally single-use tokens, also stored as hashes
|
||||
|
||||
## Rationale
|
||||
- JWTs are stateless, simple to implement, and work well with REST APIs
|
||||
- Device credentials are long-lived but can be rotated
|
||||
- Token hashing prevents database compromise from revealing usable credentials
|
||||
- Role-based authorization with hierarchy: owner > admin > operator > read_only
|
||||
|
||||
## Consequences
|
||||
- JWT secret must be configured via environment variable
|
||||
- Tokens should have reasonable expiry (24h default for users)
|
||||
- Device credentials are generated during enrollment and stored securely
|
||||
- All auth decisions are logged to the audit trail
|
||||
@@ -0,0 +1,25 @@
|
||||
# ADR-005: Device Status Calculation
|
||||
|
||||
## Status
|
||||
Accepted
|
||||
|
||||
## Context
|
||||
Devices report heartbeats at regular intervals. We need to determine online/offline status.
|
||||
|
||||
## Decision
|
||||
- Agent sends heartbeats every 30 seconds (configurable)
|
||||
- Server marks device as `online` on each received heartbeat
|
||||
- A background worker checks for stale devices every 60 seconds
|
||||
- If last heartbeat is older than 2 minutes, device is marked `offline`
|
||||
- If metrics show concerning values (disk > 90%), device is marked `warning`
|
||||
|
||||
## Rationale
|
||||
- Simple threshold-based status is reliable and easy to understand
|
||||
- Status transitions are logged for audit purposes
|
||||
- The threshold is configurable per-device or globally
|
||||
- Future: more sophisticated health scoring
|
||||
|
||||
## Consequences
|
||||
- Status is computed server-side, not trusted from the agent
|
||||
- The heartbeat interval affects status responsiveness
|
||||
- Status changes generate audit events and can trigger alerts
|
||||
Reference in New Issue
Block a user