- Add password_reset_required column (migration 004) + repository support - auth.Service.ChangePassword verifies current, hashes new, clears flag, emits PasswordChange audit events for success and failure - Bootstrap: when no ORCHESTRAD_BOOTSTRAP_PASSWORD[_FILE] is set, seed admin/admin with password_reset_required=true and log a one-time warn banner; env/file-supplied passwords keep the flag clear - Expose passwordResetRequired in UserInfo / /auth/me / login response - POST /api/v1/auth/change-password behind the authenticated group - Frontend: /change-password page + ChangePasswordForm, AuthLogin and RequireAuth bounce any other route to it while the flag is set - Docs: DesignSpecification 8.6/8.8 and Template 7.6/7.7 rewritten, Trusted Proxy renumbered to 7.8 in the template, acceptance items updated to match the new default-credential behavior
60 KiB
Active Directory Rule Automation Platform — Detailed Product & Engineering Specification
1. Purpose
Build a modern, cross-platform Active Directory rule automation platform inspired by Easy365Manager DynamicGroups, but expanded into a full rule-driven orchestration system with a web UI, REST API, secure credential management, database-backed configuration, scheduling, auditing, and extensible execution targets.
The product must avoid manual file editing entirely. All configuration, rule authoring, scheduling, testing, credential handling, and execution visibility must be managed through the UI and API.
This specification is written to guide Claude Code and/or Augment through implementation in the correct order so architectural mistakes do not force repeated rewrites.
2. Product Goals
2.1 Core Goals
- Replace static JSON-driven group management with a database-backed system.
- Support dynamic automation for Users, Computers, and Groups in Active Directory.
- Provide a modern UI for creating, testing, scheduling, and monitoring rules.
- Provide a secure and reusable credential system for directory connections.
- Expose all major operations via a REST API with Swagger/OpenAPI.
- Run as a foreground process, service, or containerized workload.
- Support install, uninstall, start, stop, init, and foreground execution from the main binary.
- Be cross-platform for the application runtime, with AD functionality implemented through LDAP-compatible operations.
- Be maintainable, centralized, and modular to avoid duplicated logic.
2.2 Non-Goals
- Direct dependence on Windows-only AD MMC tooling.
- Manual editing of configuration files as the primary administration model.
- Tight coupling between UI, scheduler, rule engine, and transport/auth logic.
- Hidden “magic” logic that cannot be tested independently.
2.3 Implementation Configuration Questions
This section defines configurable implementation choices that an AI implementer (Claude Code, Augment, or similar) must read and honor. Each question has a single authoritative answer recorded inline. If the answer is changed, every implementation section that references the question must be re-read and applied accordingly.
Questions are formatted as structured key/value blocks so automated tooling can parse them.
Question: Embed the built web UI into the backend binary?
id: embed_ui_in_binary
question: Should the built web UI be embedded into the backend binary so a single binary ships the full product (API + UI)?
allowed_values: [yes, no]
default: yes
answer: yes
Behavior contract:
- When
answer: yes(the default for this product):- The frontend must be buildable as a fully static export (
next buildwithoutput: "export"), producing a deterministic output directory (for examplefrontend/out/). - The backend must include that directory via
//go:embedand serve it from the same HTTP server that hosts the API. - The backend router must mount the embedded UI on all non-API routes as an SPA fallback, so deep links resolve to
index.html, while/api/v1/*,/healthz, and any other reserved routes continue to be handled by the API. - The build pipeline must build the frontend first, then the backend, so the embedded assets reflect the current UI.
- The single produced binary must be sufficient to run the full product without any separate web server, Node.js runtime, or static asset hosting.
- The frontend must be buildable as a fully static export (
- When
answer: no:- The backend must not embed any frontend assets and must not serve UI routes.
- The frontend is deployed separately (container, static host, reverse proxy, etc.).
- CORS must be configured explicitly for the chosen frontend origin(s).
- The build pipeline must produce the backend binary and the frontend static output as independent artifacts.
Cross-references: see Section 6.2.1 (UI Delivery Model), Section 7 (Binary Branding and Embedded Resources), and Section 24 (MVP Acceptance Criteria).
3. Product Scope
3.1 MVP Scope
The MVP must include:
- Core service runtime
- SQLite database with migrations and WAL mode
- Local authentication and OIDC authentication
- Token issuance for interactive sessions
- CSRF protection for browser-based flows
- Secure credential storage for AD connection credentials
- CRUD APIs for:
- users
- roles / permissions
- AD connections
- credentials
- schedules
- rules
- rule condition groups
- rule conditions
- rule target actions
- backups / restore jobs
- logs / job runs / summaries
- Rule engine and scheduler
- AD query test endpoint
- AD connection test endpoint
- Rule simulation / preview endpoint
- UI for all major CRUD and execution visibility
- Automatic backup and manual backup/restore flows
- Structured centralized logging with rollover and retention
- Docker deployment support
3.2 Post-MVP Scope
- High availability coordination
- Multiple scheduler workers with leader election
- Metrics / Prometheus
- WebSocket/SSE live updates
- Multi-directory tenancy
- Secret manager integrations (Vault, cloud secret stores)
- Advanced notification system
- Rule templates / import-export
- Delegated administration / business unit scoping
- Dry-run execution plans with diff approval
4. Reference Product Analysis
The reference product behavior to preserve conceptually:
- Uses a service to evaluate directory rules on a schedule.
- Uses LDAP filters and/or OU scope to derive target membership.
- Supports recurring cron-driven evaluation.
- Updates AD group membership dynamically.
- Supports backup/logging concepts.
The reference product limitations to intentionally remove:
- Reliance on manual JSON editing.
- Tight coupling of configuration storage to the service filesystem.
- Narrow scope focused only on dynamic group membership.
- Limited visibility into rule composition, simulation, and auditing.
- Operational friction for testing and troubleshooting.
5. Architectural Principles
-
Single source of truth
- Database is authoritative for all runtime configuration.
-
Separation of concerns
- UI, API, auth, scheduler, rule engine, executor, backup manager, and repository layers must be isolated.
-
Centralized reusable services
- No duplicated LDAP query-building logic, token logic, schedule parsing, encryption handling, logging, validation, or audit writing.
-
Strong typing everywhere
- Shared DTOs, enums, validators, and policy objects must be centralized.
-
Idempotent execution
- Rule execution must compute desired state vs actual state and apply only the diff.
-
Secure by default
- Least privilege, encrypted secrets, hashed passwords, CSRF, secure cookies, token expiry, audit trails.
-
Extensible from day one
- Rules, conditions, actions, schedules, and object types must be modeled so new types can be added without redesigning the schema.
-
Build in dependency order
- Foundational layers first, feature surfaces second.
6. Recommended Technology Stack
6.1 Backend
Preferred backend: Go
Reasons:
- Mature LDAP ecosystem for Active Directory work
- Strong cross-platform support
- Excellent fit for long-running services and Docker deployments
- Simpler implementation path for LDAP, LDAPS, CLDAP, Kerberos, and SPNEGO-related integrations
- Good concurrency model for parallel rule evaluation and execution
- Strong fit for a single-binary operational model
Recommended backend libraries / patterns:
- Web/API: Gin, Chi, or Fiber (prefer Chi for clean composition and maintainability)
- OpenAPI/Swagger: swaggo or an OpenAPI-first generation workflow
- DB access: sqlc + database/sql or GORM (prefer sqlc + database/sql for stronger control and lower magic)
- SQLite: modernc.org/sqlite or mattn/go-sqlite3 depending on deployment constraints
- Migrations: golang-migrate
- Scheduling: robfig/cron with a central scheduler service and support for six-field cron parsing
- Logging: zerolog, slog, or logrus with file rotation via lumberjack (prefer slog with lumberjack)
- Password hashing: argon2id
- Token signing: JWT or preferably PASETO if the implementation remains straightforward
- Encryption: AES-GCM with centralized key management and envelope-style record encryption
- LDAP / Active Directory: go-ldap/ldap/v3
- Kerberos / GSSAPI ecosystem: gokrb5 and related SPNEGO-compatible libraries where needed
- Service management:
- Windows: native Windows Service integration
- Linux: systemd-friendly service install/start/stop handling
- macOS: launchd-friendly handling
- Cross-platform helper: include a thin service-control abstraction in the binary
6.2 Frontend
- Next.js
- TypeScript
- Material UI
- Tailwind CSS
- CSS variables for theme harmony
- TanStack Query
- Zod for schema validation
- react-hook-form for forms
- The UI baseline will be pulled from
https://github.com/Grace-Solutions/Spike-NextJS-PRO-Template - The frontend should be brought in via subtree, then modified and extended according to the product requirements rather than building the admin UI from scratch
Theme and design requirements:
- Light theme
- Dark theme that is not overly black/crushed
- Auto system detection
- Persisted user preference override
- Overall visual direction should feel polished, premium, spacious, and modern
- Use layered cards, soft shadows, rounded corners, balanced whitespace, strong visual hierarchy, and dashboard-quality information density without clutter
- The final design system must remain maintainable and consistent, with centralized tokens for spacing, radii, shadows, typography, and color roles
- The adopted template must be rationalized into this product cleanly so layout primitives, auth views, data views, settings pages, and reusable dashboard components feel native to the application rather than bolted on
6.2.1 UI Delivery Model
The UI delivery model is governed by the embed_ui_in_binary question in Section 2.3. The default for this product is yes: the built UI ships inside the backend binary.
Embedded-binary mode (default):
- The frontend must be buildable as a fully static export.
next.config.mjsmust setoutput: "export"(producingfrontend/out/).- All pages and components used at runtime must be compatible with static export (no server-only Next.js features such as Route Handlers,
getServerSideProps,next/headers, or dynamic runtime-only rendering). Client components that call the backend API are fully acceptable.
- API base URL resolution (strict):
- The compiled frontend bundle must contain no hardcoded scheme, host, or port for the backend API. Any fallback used for
typeof window === "undefined"during SSR/prerender will be baked into the static chunks and will leak into production bundles; this is forbidden. - The API client must resolve the base URL in this priority order:
NEXT_PUBLIC_API_BASE_URLif explicitly provided at build time.window.location.originat runtime in the browser.- The empty string when
windowis unavailable (SSR/prerender), in which case the client must emit a relative URL (path?query) that the browser resolves against the real origin at fetch time.
- The same compiled bundle must work under any scheme, host, or port the binary is served on, including behind a reverse proxy that rewrites the public URL.
- The compiled frontend bundle must contain no hardcoded scheme, host, or port for the backend API. Any fallback used for
- Frontend route layout:
- The adopted Spike template ships a demo-oriented route layout (for example,
/auth/auth1/login,/dashboards/dashboard1) that reflects its variant showcase rather than a shipped product. Before committing the frontend, flatten these to the product's own layout (for example,/login,/,/users,/rules) and update every header link, sidebar entry, auth-context redirect, and guard redirect to match. Doing this flattening in the first frontend commit avoids repeated cross-cutting rewrites once every screen is wired to template paths.
- The adopted Spike template ships a demo-oriented route layout (for example,
- The backend must embed the exported UI using
//go:embed all:frontend/out(or an equivalent path) behind a small assets package. - The HTTP server must:
- continue to serve
/api/v1/*,/healthz, and any other backend-owned routes from their existing handlers - serve static assets from the embedded filesystem for all other routes
- implement an SPA fallback: when a GET request for a non-API route does not match a static file, return
index.htmlwith HTTP 200 so client-side routing works - serve assets with appropriate
Content-Typeand long-lived cache headers for hashed/chunked assets
- continue to serve
- The build pipeline must build the frontend before the backend. If
frontend/outis missing when building the backend, the build must fail with a clear, actionable error rather than producing a binary that serves a 404 for the UI. - The single produced binary must fully host the product. No separate Node.js runtime, reverse proxy, or static file server is required for normal operation.
- In development, the embedded flow is not required; running
next devagainst the backend API over CORS is acceptable for developer ergonomics as long as the production build still uses the embedded flow.
Separate-deployment mode (when embed_ui_in_binary: no):
- The backend must not serve any UI routes and must not embed frontend assets.
- The frontend is built and deployed as an independent artifact (container, static host, or CDN).
- CORS must be configured explicitly for the frontend origin(s); localhost must remain allowed for development.
- Versioning must still ensure the UI and backend report the same version at runtime so operators can verify they are paired correctly.
Frontend Auth Integration Note
- The Spike template uses NextAuth (Auth.js) by default
- Use NextAuth/Auth.js for interactive browser authentication and session management only
- Support OIDC providers via NextAuth
- Support local authentication via NextAuth Credentials provider, with credential verification performed by the backend
- The backend (Go API) remains the source of truth for authorization, RBAC, API keys, and all business/security decisions
- Do not use NextAuth as the backend security boundary or for service-to-service authentication
- API keys remain a separate authentication mechanism and must not be integrated into NextAuth
- CSRF, cookies, and session handling must align with backend expectations
- The integration approach (session strategy, cookie vs token bridging, callbacks) must be decided early and implemented centrally to avoid rework
6.3 Database
- SQLite
- WAL mode enabled by default
- Foreign keys enabled
- UUIDv4 for all PK/FK
- UTC timestamps everywhere
- soft delete support where meaningful
- schema migration support from day one
7. Runtime Modes
The main binary must support the following command model:
-
app init- validates config/env
- initializes database
- performs migrations
- ensures encryption keys exist or are valid
- installs service
- starts service
-
app install- installs service only
-
app uninstall- stops service if running
- uninstalls service
-
app start- starts installed service
-
app stop- stops installed service
-
app run- runs in foreground
-
app migrate- apply database migrations
-
app backup- creates manual backup
-
app restore --file <path>- restores database from backup safely
-
app doctor- validates DB, migrations, env vars, OIDC config, crypto keys, and storage paths
Runtime behavior requirements
- Foreground mode must behave identically to service mode except for service-control hooks.
- Signal handling must support graceful shutdown.
- Docker image should default to foreground mode.
- Logs must go to stdout in containers and also optionally to rolling files.
Binary Branding and Embedded Resources
- A product icon will exist in
/resources/icons - The Windows build must embed that icon into the Windows binary/executable metadata during build
- The build process must fail clearly if the required icon asset is missing or invalid for the Windows build target
- Windows build metadata should be centralized so icon/version information is not duplicated across scripts or project files
- When
embed_ui_in_binary: yes(see Section 2.3), the built web UI must also be embedded into the backend binary via//go:embedand served by the backend HTTP server as described in Section 6.2.1. The build must fail clearly if the expected UI output directory is missing or empty so a binary without a UI is never produced silently.
Versioning Requirements
- Version semantics must follow the exact format
yyyy.MM.dd.HHmm - Build scripts must generate and apply the same version consistently across:
- backend binaries
- Windows executable metadata where applicable
- release artifacts
- Docker image tags if desired
- API/system version reporting endpoints
- UI-visible version display
- The version must be centrally generated once per build so all outputs stay aligned
Multi-Platform Build Output Requirements
Build automation must produce binaries and copy them into a centralized /binaries folder using a predictable structure.
Recommended structure:
/binaries
/windows
/amd64
/arm64
/macos
/amd64
/arm64
/linux
/amd64
/arm64
Requirements:
- build scripts must compile for Windows, macOS, and Linux
- build scripts must compile for both 64-bit x86 and ARM64 where supported
- build scripts must copy final artifacts into the correct
/binaries/<os>/<arch>folder automatically - artifact naming must be predictable and include the product name and version where useful
- any required companion files should be copied in a similarly deterministic manner
8. Authentication & Authorization
8.1 Authentication Methods
Support both:
- local authentication
- OIDC authentication
Local authentication
- Local users stored in DB
- Passwords hashed with Argon2id
- Password reset flow for admin-created local users
- First admin bootstrap flow must be supported securely (see Section 8.6)
OIDC authentication
- OIDC login button in UI
- Auto user creation on first successful OIDC login
- Map standard claims:
- sub
- preferred_username
- given_name
- family_name
- groups if present
- Optional default role mapping rules for first login
8.2 Session and Token Model
- Interactive login endpoint issues tokens for browser/UI sessions
- Browser flow should use secure HTTP-only cookie for session/access token handling where appropriate
- Separate CSRF token for browser mutations
- Token expiry and refresh policy must be centralized
- Logout must revoke refresh/session state server-side if session store is used
API Keys
API keys must be a separate authentication model from interactive user authentication.
Requirements:
- API keys must not reuse browser session tokens or interactive login flows
- API keys must be independently issued, tracked, revoked, and audited
- API keys may be configured to either:
- expire at a defined UTC timestamp, or
- never expire
- API keys must support enable/disable and revocation
- API keys must be associated with an owning user or service identity for accountability, but authentication must remain logically separate from user session auth
- API key permissions/scopes should be extensible from day one even if MVP starts with broad API access for admins only
- API keys must be shown in full only once at creation time
- After creation, only a non-sensitive preview should be stored/displayed, such as:
- key name
- prefix / partial masked value
- created time
- expiry state
- last used time
- enabled state
- The full plaintext API key must never be retrievable again after creation
- The UI modal/dialog for newly created API keys must include:
- warning that the key will only be shown once
- masked/unmasked reveal behavior if desired
- copy-to-clipboard button
- explicit confirmation/acknowledgement before dismissing if practical
- Stored API keys must be protected using a secure one-way hash or a split-token pattern so server-side verification does not require plaintext storage
- API key usage must be audited, including creation, revoke, delete, and last-used tracking
8.3 CSRF Requirements
- CSRF required for browser-authenticated mutation requests
- Token transport pattern must be standardized and centrally enforced
- Exempt non-browser bearer-token-only API usage when appropriate
8.4 Authorization
RBAC minimum roles:
- SuperAdmin
- Admin
- Operator
- Viewer
Permissions should be action-based and centrally defined, not scattered in route handlers.
8.5 Route Protection Middleware
Route protection must be enforced by a middleware-based gate from the very first HTTP commit, not bolted on after feature routes ship. The router must be organized so protection is the default and exposure is the explicit exception.
Requirements:
- The
/api/v1router must be split into a public allowlist and an authenticated group. The public allowlist must be short and reviewable; everything else must live inside the authenticated group and inherit protection by construction. - The authenticated group must wrap every administrative resource — users, API keys, audit, settings, credentials, AD connections, schedules, rules, rule runs, backups, config export/import, dashboard — with the standard auth middleware that validates the session/token and attaches the resolved principal to the request context.
- The public allowlist for this product contains only:
/api/v1/version,/api/v1/health,/api/v1/auth/login,/api/v1/auth/logout,/api/v1/auth/csrf, and the OIDC/api/v1/auth/oidc/start/:providerand/api/v1/auth/oidc/callback/:providerendpoints. No other route may be placed outside the authenticated group without an explicit, documented justification. - Adding a new administrative resource must not require remembering to attach middleware. Code review must reject any change that mounts a handler outside the authenticated group without an explicit public-allowlist rationale.
- Integration tests must assert that each protected route returns 401 without a token and 2xx with a valid token, and that each public route works without a token. Both directions must be covered so the gate cannot silently regress.
- On startup, the server must emit a single log line enumerating the public-allowlist routes so operators can audit the unauthenticated surface at boot.
8.6 First-Run Admin Bootstrap
On a fresh data directory, the product must be usable immediately without requiring the operator to hand-craft a user row or edit a config file.
Requirements:
- After migrations complete on startup, the backend must check whether any user exists. If the users table is empty, it must create a single user (username
admin) with theAdminrole. - The initial password source must follow this precedence:
ORCHESTRAD_BOOTSTRAP_PASSWORDorORCHESTRAD_BOOTSTRAP_PASSWORD_FILEif present (see Section 9.1). This path is treated as an operator-provided credential and does not force a password change on first login.- A fixed default password of
admin. When this path is taken thepassword_reset_requiredflag on the user must be set so the first successful login is immediately redirected to the password-change flow (see Section 8.8) before any other UI or API is reachable.
- When the default-password path is taken, a clearly marked one-time banner must be printed to stdout and written to the structured log at warn level, stating the seeded username, the default password, and the requirement to change it on first login.
- The bootstrap must be a no-op when any user already exists; it must never reset or downgrade an existing administrator's password.
- The bootstrap must be wired into the
runcommand so it executes on every startup after migrations (the existence check keeps it idempotent).
8.8 Forced Password Change
When a user's password_reset_required flag is set (e.g. the default-password bootstrap path in Section 8.6, or an administrator-triggered reset), the product must force a password change before any other functionality becomes reachable.
Requirements:
- The users table must carry a
password_reset_requiredboolean column, included in/api/v1/auth/loginand/api/v1/auth/meresponses aspasswordResetRequired. - A
POST /api/v1/auth/change-passwordendpoint, gated by the authenticated group (Section 8.5), must accept{ currentPassword, newPassword }, verify the current password, enforce a minimum length, replace the hash, clearpassword_reset_required, and emit aPasswordChangeaudit event (success or failure). - The frontend login flow must redirect to
/change-passwordwhenever the login response carriespasswordResetRequired: true. The authenticated route guard must bounce any other protected route to/change-passwordas long as the flag is set. - The
/change-passwordpage must work with the session token the user just obtained; failures must surface the backend error message (invalid current password, password too short, new password unchanged, etc.) without clearing the form.
8.7 Trusted Proxy Middleware
When OrchestrAD is deployed behind a reverse proxy or load balancer, X-Forwarded-* headers must be honored without making the service spoofable from arbitrary clients.
Requirements:
- Trust for forwarded headers must be opt-in and driven by
ORCHESTRAD_TRUSTED_PROXIES, a comma-separated list of CIDRs. The default must be empty — no forwarded headers are trusted. - A trusted-proxy middleware must run before authentication, authorization, and audit logging. When the immediate peer address matches a trusted CIDR, the middleware must rewrite
RemoteAddrfromX-Forwarded-Forand the request scheme fromX-Forwarded-Proto. When the peer is not trusted, allX-Forwarded-*headers must be ignored and the direct connection address must be used. - Downstream handlers, audit events, rate limiters, and security decisions must consume the middleware's normalized request values rather than re-reading raw forwarded headers.
9. Encryption, Secrets, and Key Management
9.1 Application Secret Inputs
Allow secret/key material via:
- environment variable
- secrets file / mounted secret
Support a 32-byte key minimum for encryption/signing operations.
Env-or-file indirection (mandatory for all secret-bearing variables)
- The
ORCHESTRAD_prefix is the single authoritative namespace for application configuration. All configurable values use this prefix (for exampleORCHESTRAD_PORT,ORCHESTRAD_DATA_PATH,ORCHESTRAD_ENCRYPTION_KEY). Per-feature prefixes must not be invented. - Every variable that carries a secret or credential (encryption keys, bootstrap password, OIDC client secret, signing keys, reserved future fields) must also accept an indirect file-based form: for each
ORCHESTRAD_FOO, the loader must also honorORCHESTRAD_FOO_FILEpointing at a path on disk whose contents are the value. This matches the Docker / Kubernetes / systemd secret-mounting idiom and avoids baking secrets into the process environment. - Precedence: the direct value wins over the file-backed value if both are present; an explicit empty string wins over an absent variable. The loader must trim trailing whitespace/newlines from file-backed values so a trailing newline in a mounted secret does not corrupt the value.
- The config-loading helper must be centralized so the
_FILEindirection is applied uniformly across every key without per-call-site logic.
9.2 Protected Data
Encrypt at rest:
- AD bind passwords
- other reusable credentials
- OIDC client secrets
- future secret fields
9.3 Secret Storage Design
Use envelope-style design:
- application master key from env/secret source
- per-record random nonce/iv
- authenticated encryption (AEAD)
Never store plaintext secrets in DB or logs.
9.4 Audit Redaction
Sensitive values must be redacted in:
- logs
- audit entries
- API responses
- UI screens after create/update
10. Active Directory Connectivity Model
10.1 AD Connection Object
Create reusable AD connection objects with fields such as:
- id
- name
- enabled
- host(s) / server / domain controller list
- port
- use_tls
- start_tls
- allow_invalid_certificates (default false; expose but discourage)
- root_dn
- bind_dn or bind_username
- credential_id
- default_object_scope
- search_scope (Base / OneLevel / Subtree)
- timeout_seconds
- paging_enabled
- page_size
- connection notes
- created_utc
- updated_utc
- deleted_utc
10.2 AD Connection Testing
Must support test actions:
- test TCP/connectivity
- test bind/authentication
- test root DN accessibility
- test sample search
- return normalized diagnostics
10.3 AD Query Features
Support querying for:
- users
- computers
- groups
Support base settings:
- root path / base DN
- recursive/subtree selection
- object type filter
- paging
- attribute selection
- custom LDAP fragment
11. Credential Object System
Credentials must be reusable, securable, and testable.
11.1 Credential Object Types
At minimum:
- UsernamePassword
- future extensibility for certificate / SASL / token-backed integrations
11.2 Credential Fields
- id
- name
- description
- credential_type
- username
- encrypted_secret
- enabled
- last_tested_utc
- last_test_result
- created_utc
- updated_utc
- deleted_utc
11.3 Credential Usage
- credentials referenced by AD connections
- references validated before delete
- optional usage summary in UI
12. Rule Engine Domain Model
Rules are the core product abstraction.
12.1 Rule Object
Fields:
- id
- name
- description
- enabled
- ad_connection_id
- object_type (
User,Computer,Group) - base_dn_override (optional)
- search_scope_override (optional)
- schedule_id
- execution_mode (
Apply,PreviewOnly) - max_parallelism_override (optional)
- stop_on_error (default false)
- created_utc
- updated_utc
- deleted_utc
12.2 Condition Group Model
A rule has one or more condition groups. Each condition group can be enabled/disabled. Each condition group has a logical join operator.
Fields:
- id
- rule_id
- name
- enabled
- join_operator (
AND,OR) - sort_order
- negate
- created_utc
- updated_utc
- deleted_utc
Interpretation:
- within a group, conditions combine via group join operator
- across groups, define a rule-level group join operator or nested model
Recommended simplification for maintainability
For MVP:
- all groups combine at rule level with a single
group_join_operator - nested arbitrary trees deferred to post-MVP
12.3 Condition Model
Fields:
- id
- condition_group_id
- enabled
- attribute_name
- operator
- value_type
- comparison_value
- custom_ldap_expression
- negate
- sort_order
- case_sensitive
- created_utc
- updated_utc
- deleted_utc
Supported operators:
- Equals
- NotEquals
- Regex
- CustomLdap
- GreaterThan
- LessThan
- Contains
- StartsWith
- EndsWith
- Exists
- NotExists
Notes:
CustomLdapshould allow advanced direct LDAP expression injection in a controlled wayRegexmust be validated before save- comparison value typing should support string, int, bool, datetime where possible
12.4 Rule Target Action Model
A rule supports one or more target actions. Each action can be enabled/disabled. Actions execute in deterministic order.
Fields:
- id
- rule_id
- action_type
- enabled
- sort_order
- configuration_json
- rollback_mode
- created_utc
- updated_utc
- deleted_utc
MVP Action Types
- MoveToOu
- AddToGroup
- AddGroupToGroup
- EnsureGroupExists
- RemoveFromGroupIfNoLongerMatched
Future Action Types
- DisableAccount
- EnableAccount
- SetAttribute
- ClearAttribute
- CreateOuIfMissing
- MoveGroupToOu
- CreateUserHomeFolder trigger/integration
- Send notification
13. Dynamic Path & Variable Expansion
Dynamic destination and target fields must support variable expansion.
13.1 Variable Sources
- rule metadata
- current object attributes from AD
- execution timestamps
- static literals
13.2 Syntax
Use a single standardized syntax, for example:
{{object.department}}{{object.country}}{{object.cn}}{{now.utc_date}}{{rule.name}}
13.3 Use Cases
- dynamic OU paths
- dynamic group names
- dynamic descriptions
- dynamic group OU placement
13.4 Safety Rules
- variable resolution failure handling must be explicit
- invalid path output must fail validation or fail execution with clear diagnostics
- escaping rules must be centralized
14. Scheduling
14.1 Schedule Object
A reusable schedule table must exist.
Fields:
- id
- name
- description
- enabled
- schedule_kind (
Easy,Cron) - easy_interval_value
- easy_interval_unit
- cron_expression
- timezone_mode (
UTCdefault; optionally local later) - created_utc
- updated_utc
- deleted_utc
14.2 Easy Schedule Support
Examples:
- every 5 minutes
- every 15 minutes
- every 1 hour
- every day
14.3 Custom Cron
Use six-field cron as requested. Validate before save. Store normalized next-run preview.
14.4 Scheduler Requirements
- scheduler loop separate from API request threads
- ability to disable schedules/rules without deletion
- missed run policy must be explicit
- prevent overlapping execution of the same rule unless explicitly allowed later
15. Rule Evaluation and Execution Engine
15.1 High-Level Flow
For each eligible scheduled rule:
- Load rule definition and dependencies.
- Validate referenced connection, credential, and schedule state.
- Build effective directory search query.
- Fetch candidate objects.
- Evaluate condition groups.
- Produce match set.
- Build desired action plan.
- Compare desired state vs actual state.
- Apply diffs idempotently.
- Record run result, actions, durations, and errors.
- Update summary tables.
15.2 Concurrency Model
- multiple rules may execute concurrently
- each rule execution must have bounded concurrency
- a single rule should not overlap with itself
- executor pool should be configurable globally and per rule
15.3 Diff-Based Execution
For membership-related actions:
- compute current members
- compute desired members
- add missing members
- optionally remove no-longer-matching members
This must be configurable per action/rule.
15.4 Dry Run / Preview
Rule preview must show:
- matched objects
- unmatched objects if useful
- planned additions
- planned removals
- destination OU/group resolution
- validation warnings
16. Active Directory Operation Semantics
16.1 MoveToOu
Capabilities:
- move matched object to target OU
- create OU path if not exists (optional per action)
- support dynamic path expansion
- validate DN/path before execution
16.2 AddToGroup
Capabilities:
- add matched objects to target AD group
- auto-create group if missing (optional)
- specify group type/scope when auto-creating:
- Global
- DomainLocal
- Universal
- Security
- Distribution
- optional target OU for created group
- optional removal when object no longer matches
16.3 AddGroupToGroup
Capabilities:
- allow group objects to be added to parent groups
- validate group nesting constraints where applicable
16.4 EnsureGroupExists
Capabilities:
- ensure target group exists before downstream operations
- support dynamic naming if needed
- support OU placement and type selection
17. Data Model Requirements
17.1 Global Entity Standards
Every major table should include:
idUUIDv4 PKcreated_utcupdated_utc- optional
deleted_utc
17.2 Core Tables
At minimum:
- users
- roles
- user_roles
- sessions or refresh_tokens
- api_keys
- oidc_providers
- credentials
- ad_connections
- schedules
- rules
- rule_condition_groups
- rule_conditions
- rule_actions
- backup_jobs
- restore_jobs
- rule_runs
- rule_run_actions
- audit_events
- app_settings
- config_exports
- summary_rule_stats
- summary_connection_stats
- summary_execution_stats
17.3 Summary Tables
Purpose:
- avoid expensive dashboard queries
- speed UI insights
Examples:
- rule success/failure counts
- last run per rule
- average duration
- objects processed
- action counts
- connection health summary
These may be maintained transactionally or asynchronously depending on complexity.
18. Backups, Restore, and Retention
18.1 Automatic Backups
- automatic DB backups on a schedule and/or before migrations/restore operations
- default max backup count: 3
- configurable retention count
18.2 Manual Backups
Allow user-triggered backup from API/UI/CLI.
18.3 Restore
Allow restore from backup with safeguards:
- confirm operation
- create pre-restore safety backup
- validate backup readability
- log restore event in audit trail
18.4 Backup Storage
- configurable storage path
- metadata stored in DB
- retention cleanup automatic
18.5 Configuration Export and Import
The system must support clean export and import of configuration data so environments can be migrated, cloned, versioned, or restored without manual database editing.
Export Requirements
Exportable configuration must include, at minimum:
- AD connections
- schedules
- rules
- rule condition groups
- rule conditions
- rule actions
- app settings relevant to feature behavior
- OIDC provider configuration where appropriate
- API key metadata if desired, but never the secret values themselves
- credential metadata, but not decryptable plaintext secrets
Export behavior:
- export format should be JSON initially, with stable schema/version metadata
- exported files must include format version and export timestamp in UTC
- exports must preserve UUIDv4 identifiers when appropriate for clean re-import/mapping
- exports must be designed so they can be imported into another instance cleanly
- secrets must never be exported in plaintext
- encrypted credential blobs may be exported as-is only when safe and explicitly intended
Import Requirements
- imports must support validation before apply
- imports must support dry-run preview showing creates, updates, conflicts, and skipped records
- imports must support idempotent behavior where practical
- imports must preserve relationships across schedules, rules, condition groups, conditions, and actions
- imports must handle schema/version migration logic explicitly
Credential Portability Rules
Credential handling must follow these rules:
- if the destination instance uses the same application encryption keys, encrypted credential payloads may remain usable after import
- if the destination instance does not use the same encryption keys, imported credential records must remain present as metadata but marked as requiring secret re-entry
- the UI and API must clearly indicate which imported credentials are not usable until secrets are re-entered
- once re-entered, the secret must be encrypted using the destination instance key material
- rule/config imports must remain clean even when associated credentials require re-entry
API Key Portability Rules
- API key plaintext values must never be exportable
- API keys imported from configuration should be treated as metadata-only unless a deliberate secure reissue flow is implemented
- imported API keys should default to disabled or require regeneration unless there is a secure portability design in place
19. Logging, Auditing, and Observability
19.1 Centralized Logging
Use a logging library that supports:
- file rollover
- size/time-based rotation
- retention cleanup
- stdout sink
- structured fields when useful internally
Logging format requirement:
- Standard logs:
[TimestampUTC] - [Component] - [Level] - Message - Error logs:
[TimestampUTC] - [Component] - [Level] - [File:Line:Column] - Message
Logging style requirements:
- logs must be plain and easy to understand
- avoid dumping large stack traces into routine logs
- errors should be summarized clearly with relevant context first
- detailed error internals should be available only where appropriate for debugging, not sprayed everywhere in normal logs
- messages should communicate what is happening before, during, and after an operation where practical
- for long-running work, emit progress-oriented messages at a reasonable cadence without flooding the log
19.2 Log Content
Include:
- timestamp (UTC)
- component
- level
- message
- correlation id / execution id where relevant
- rule id / action id when relevant
- duration where relevant
19.3 Audit Trail
Audit events required for:
- login success/failure
- CRUD changes
- credential tests
- connection tests
- rule runs
- backup/restore
- service lifecycle events
19.4 Sensitive Data Handling
Secrets and sensitive fields must be redacted.
20. REST API Requirements
20.1 API Design Principles
- versioned API path:
/api/v1 - OpenAPI/Swagger generation from source
- resource-oriented routes
- consistent error envelope
- server-side validation
- pagination / filtering / sorting for list endpoints
- the router must be split into a public allowlist and an authenticated group as described in Section 8.5; administrative resources must inherit auth by construction rather than by remembering to attach middleware per handler
- CORS and trusted proxy handling follow Sections 20.1.1 and 8.7 respectively
20.1.1 CORS Defaults
- In the default embedded-UI deployment (Section 2.3,
embed_ui_in_binary: yes), the UI and API share one origin; the default CORS allowlist must be empty and no cross-origin access is granted. - Cross-origin origins must only be populated when an operator sets
ORCHESTRAD_ALLOWED_ORIGINSexplicitly, typically for development againstnext devor for the separate-deployment mode. - When running in the separate-deployment mode (
embed_ui_in_binary: no), production CORS origins must be explicitly configured and localhost must remain allowed for development.
20.1.2 Route Groups
The router must physically express two groups:
- Public group — no authentication middleware. Allowed membership for MVP:
GET /api/v1/versionGET /api/v1/healthPOST /api/v1/auth/loginPOST /api/v1/auth/logoutGET /api/v1/auth/csrfGET /api/v1/auth/oidc/start/:providerGET /api/v1/auth/oidc/callback/:provider
- Authenticated group — wraps every other route under
/api/v1with the standard auth middleware. All administrative resources (users, roles, api-keys, credentials, ad-connections, schedules, rules, rule-runs, rule-actions, backups, audit, settings, config, dashboard) live here and inherit protection automatically.
The startup log must emit a single line listing the public routes so operators can audit the unauthenticated attack surface.
20.2 Major Resource Areas
- auth
- users
- roles
- oidc providers
- credentials
- ad connections
- schedules
- rules
- rule previews
- rule runs
- rule actions
- logs
- backups
- restore
- system health
- settings
20.3 Example Endpoint Groups
Auth
POST /api/v1/auth/loginPOST /api/v1/auth/logoutGET /api/v1/auth/meGET /api/v1/auth/csrfGET /api/v1/auth/oidc/start/:providerGET /api/v1/auth/oidc/callback/:provider
API Keys
GET /api/v1/api-keysPOST /api/v1/api-keysPOST /api/v1/api-keys/:id/revokePOST /api/v1/api-keys/:id/enablePOST /api/v1/api-keys/:id/disableDELETE /api/v1/api-keys/:id
Config Export / Import
POST /api/v1/config/exportPOST /api/v1/config/import/validatePOST /api/v1/config/import
AD Connections
POST /api/v1/ad-connections/testPOST /api/v1/ad-connections/:id/testPOST /api/v1/ad-connections/:id/query-preview
Rules
POST /api/v1/rules/:id/previewPOST /api/v1/rules/:id/runPOST /api/v1/rules/:id/enablePOST /api/v1/rules/:id/disable
Backups
POST /api/v1/backupsPOST /api/v1/backups/:id/restore
21. UI Requirements
21.1 UX Principles
- No manual config file editing anywhere
- Clear step-by-step flows for creating connections, credentials, schedules, and rules
- Safe defaults with advanced options collapsible
- Strong validation and live feedback
- Test/preview before save where possible
21.2 Primary UI Areas
- Dashboard
- Authentication views
- Users & roles
- API Keys
- OIDC configuration
- Credentials
- AD Connections
- Schedules
- Rules
- Rule Builder
- Rule Preview / Simulation
- Rule Runs / History
- Backups / Restore
- Config Export / Import
- Settings
- Logs / Audit
21.3 Rule Builder Experience
The rule builder must be significantly easier than raw LDAP/JSON.
Recommended UX:
- Select object type
- Select AD connection
- Optional base/scope override
- Add condition groups visually
- Add conditions using dropdown operators
- Add actions
- Select schedule
- Preview
- Save
Rule builder features
- enable/disable toggles at rule/group/condition/action level
- drag sort order for groups/actions
- LDAP preview helper
- attribute pickers where possible
- cron helper with natural-language preview
- variable insertion helper
- dry-run output panel
22. Maintainability Rules for the Codebase
These are implementation mandates.
- No duplicated DTOs for same entity across layers unless absolutely necessary.
- Centralize enums and validation rules.
- Centralize LDAP query construction and AD operation wrappers.
- Centralize authorization policies.
- Centralize audit event writing.
- Centralize error types and API response mapping.
- Centralize timestamp creation in UTC.
- Centralize UUID generation policy.
- Avoid raw SQL duplication by keeping repositories/query modules organized by aggregate.
- Keep frontend forms schema-driven where practical.
- Create shared frontend types from OpenAPI or a shared schema pipeline.
- No business logic in route handlers or React components.
- Logging helpers and error formatting must be centralized so log style and error clarity remain consistent.
- Errors must be wrapped in a standardized structure that captures component, file, and line information automatically where possible.
- Decisions around NextAuth integration versus backend-auth bridging must be made once, documented, and implemented centrally.
- Route protection must be structural, not per-handler: the public allowlist and authenticated group are the only two places a route can live. Per-handler auth attachment is forbidden.
- Forwarded header handling must live in a single middleware (Section 8.7); downstream code must not re-read
X-Forwarded-*directly. - Secret-bearing environment variables must flow through a centralized env-or-file loader (Section 9.1); per-call-site
os.Getenvfor secrets is forbidden.
23. Suggested Project Structure
/resources
/icons
/binaries
/windows
/amd64
/arm64
/macos
/amd64
/arm64
/linux
/amd64
/arm64
/backend
/frontend
23.1 Backend
/backend
/src
/api
/auth
/config
/crypto
/db
/migrations
/repositories
/directory
/ldap
/models
/operations
/logging
/scheduler
/rules
/engine
/models
/preview
/executor
/backup
/audit
/services
/system
/types
/validation
main.rs
23.2 Frontend
/frontend
/src
/app
/components
/features
/auth
/dashboard
/connections
/credentials
/rules
/schedules
/backups
/logs
/settings
/lib
/hooks
/schemas
/theme
/types
Frontend Design System Expectations
- establish a centralized design system layer for colors, typography, spacing, radii, shadows, layout containers, and reusable dashboard primitives
- create reusable page shells, stat cards, action bars, table wrappers, detail panes, settings layouts, modal patterns, and auth layouts
- the visual baseline should be inspired by the Flexy dashboard reference and its repository structure, which present a polished Material UI dashboard style with rich cards, auth pages, tables, charts, settings views, and multi-section admin layouts
- the implementation must not merely copy the reference; it should adapt that quality level and visual polish to this product’s domain-specific workflows and information architecture
24. Implementation Order (Critical)
This order is mandatory to avoid rewrites.
Phase 1 — Foundations
- Repository structure
- configuration loading with the env-or-file secret indirection pattern (Section 9.1)
- centralized logging
- app secret/key loading
- database bootstrap
- migrations framework
- base entity patterns (UUIDv4, UTC timestamps, soft delete helpers)
- HTTP server skeleton with the public/authenticated route split (Section 8.5) and the trusted-proxy middleware (Section 8.7) wired in before any real handlers are mounted
- health endpoint (on the public allowlist)
- service/foreground runtime abstraction
- CLI commands for run/install/uninstall/start/stop/init
- centralized version generation in
yyyy.MM.dd.HHmmformat - multi-platform build script scaffolding
- Windows resource embedding for icon/version metadata
- binary output copying into
/binaries/<os>/<arch>
The router composition and trusted-proxy middleware belong in Phase 1, not Phase 2. Adding routes first and bolting on authentication or header trust later is an explicit anti-pattern: any resource added before the gate exists becomes an implicit public endpoint, and closing that gap after the fact requires re-auditing every mounted handler.
Deliverables
- binary runs in foreground
- DB initializes correctly
- logging works with rollover/retention
- migrations apply safely
/api/v1/healthand/api/v1/versionreachable publicly; any placeholder route mounted inside the authenticated group returns 401 without a token
Phase 2 — Auth and Security Core
- local user model
- password hashing (Argon2id)
- login/logout/me endpoints (login/logout/csrf on the public allowlist; me on the authenticated group)
- session/token issuance and the auth middleware that feeds the authenticated group established in Phase 1
- first-run admin bootstrap using
ORCHESTRAD_BOOTSTRAP_PASSWORD/_FILEor the fixedadmin/admindefault with the forced-change flag (Sections 8.6 and 8.8), wired into theruncommand immediately after migrations - forced password change endpoint and frontend route (Section 8.8) that runs before any other authenticated UI or API is reachable when the flag is set
- CSRF support
- RBAC framework
- audit event core, consuming the trusted-proxy middleware's normalized values
- OIDC provider config model
- OIDC login flow with auto user creation
Deliverables
- secure local login
- secure OIDC login
- working RBAC guards
Phase 3 — Core Domain Models
- credentials tables/services
- AD connection tables/services
- schedules tables/services
- API key tables/services
- configuration export/import model and schema versioning
- rules tables/services
- condition groups / conditions / actions tables/services
- CRUD endpoints for all above
- frontend CRUD screens
Deliverables
- full admin CRUD for all foundational entities
Phase 4 — Directory and Rule Execution Core
- LDAP connection abstraction
- connection testing
- query preview
- rule evaluation engine
- condition translation/evaluation
- action planning model
- preview mode
- apply mode for AddToGroup and RemoveFromGroupIfNoLongerMatched
- rule runs history
- summary table updates
Deliverables
- dynamic group parity achieved, but database/UI-driven
Phase 5 — Advanced AD Actions
- MoveToOu
- EnsureGroupExists
- AddGroupToGroup
- OU auto-create if missing
- dynamic path variable expansion
- stronger validation and previews
Deliverables
- richer than reference product
Phase 6 — Backup, Restore, and Operations
- backup manager
- retention cleanup
- manual backup API/UI
- restore API/UI/CLI
- doctor command
- log viewer / audit UI
Deliverables
- operationally complete system
Phase 7 — UX Hardening and Polish
- dashboard summaries
- better rule builder UX
- cron helper and natural-language schedule previews
- form refinements
- empty states / guided onboarding
- performance profiling
- documentation
25. Testing Strategy
25.1 Backend
- unit tests for validators, auth, crypto, cron parsing, variable expansion
- integration tests for DB repositories
- integration tests for auth flows
- integration tests for LDAP query translation
- rule evaluation tests with fixtures
- backup/restore tests
25.2 Frontend
- component tests for forms and guards
- integration tests for rule builder
- theme tests
- auth flow tests
25.3 End-to-End
- bootstrap admin
- create credential
- create AD connection
- test connection
- create schedule
- create rule
- preview rule
- run rule
- inspect history
- backup database
- restore database
26. Security Requirements Checklist
- Argon2id password hashing
- AEAD encryption for secrets
- secure cookie flags where cookies are used
- CSRF for browser mutations
- brute-force resistant login controls or rate limiting
- input validation on all API endpoints
- output encoding in UI
- strict CORS policy
- redact secrets in logs
- audit all privileged actions
- validate OIDC issuer and audience
- token expiry and rotation policy
- least-privilege AD service account guidance in docs
27. Performance and Scalability Notes
- SQLite is acceptable for initial scope if writes are serialized carefully and long transactions are avoided.
- WAL mode will improve concurrent read behavior.
- summary tables are required to avoid expensive dashboard queries.
- LDAP paging should be used for large queries.
- rule execution pool must be bounded.
- for future scale, repositories and services should be designed so SQLite can be replaced later if needed.
28. Docker Requirements
- single container for app runtime acceptable
- configurable data path bind mount
- configurable backup path bind mount
- configurable logs path bind mount
- healthcheck endpoint
- container defaults to foreground mode
- environment variables for DB path, backup path, secrets, OIDC config, log settings
Example runtime expectations:
/data/app.db/data/backups/data/logs
29. Documentation Deliverables
Claude Code / Augment should produce documentation for:
- architecture overview
- setup and deployment
- environment variables
- service commands
- backup/restore
- OIDC setup
- local auth setup
- AD credential delegation guidance
- rule builder guide
- variable expansion guide
- API usage guide
- troubleshooting guide
30. Explicit Build Guardrails for Claude Code / Augment
These are hard constraints:
- Do not start with UI mockups before backend foundations exist.
- Do not hardcode business rules in components.
- Do not duplicate schemas between backend and frontend manually unless unavoidable.
- Do not implement arbitrary nested condition trees in MVP.
- Do not implement advanced features that bypass audit logging.
- Do not store plaintext secrets anywhere.
- Do not skip migrations, even early.
- Do not treat filesystem config as authoritative.
- Do not build ad hoc service-control logic separately for each platform.
- Do not intertwine LDAP operations with HTTP handlers.
- Do not mount any
/api/v1route outside the authenticated group without adding it to the Section 8.5 public allowlist with a documented rationale. Attaching auth per handler is forbidden; the router must inherit protection by construction. - Do not trust
X-Forwarded-*headers anywhere outside the trusted-proxy middleware, and do not ship a non-empty default forORCHESTRAD_TRUSTED_PROXIES. - Do not hardcode a backend scheme/host/port anywhere in the frontend bundle, including as a "safe" fallback for SSR/prerender. Return an empty string and build relative URLs (Section 6.2.1).
- Do not adopt the Spike template's demo route layout as-is. Flatten to the product's own routes in the first frontend commit so later features are not wired to paths that must then be rewritten.
- Do not require the operator to hand-craft a user row to log in on first run. The bootstrap flow in Section 8.6 is mandatory.
31. MVP Acceptance Criteria
The MVP is complete when:
- The binary can run foreground and in service mode.
- The binary supports install, uninstall, start, stop, and init.
- The app runs in Docker.
- SQLite WAL, migrations, backups, and restore are working.
- Local auth and OIDC auth both work via NextAuth integration.
- Browser flows are CSRF protected.
- Tokens are issued securely on login.
- API keys are separate from interactive auth, can expire or never expire, and are only shown once at creation.
- AD credentials and connections can be created and tested.
- Rules for Users, Computers, and Groups can be authored in the UI.
- Rules support enabled/disabled states at multiple levels.
- Schedules support easy presets and six-field cron.
- Rules can preview and run.
- Add-to-group and optional remove-on-diff work.
- Move-to-OU and auto-create targets work.
- Group auto-create and group nesting are supported.
- Configuration can be exported and imported cleanly.
- Imported credentials remain usable only when encryption keys match; otherwise they are flagged for secret re-entry.
- The build system embeds the Windows icon from
/resources/iconsinto the Windows binary. - The version format
yyyy.MM.dd.HHmmis applied consistently across binaries and version reporting. - Build outputs are copied into
/binaries/windows|macos|linux/amd64|arm64predictably. - The UI is based on the Spike NextJS PRO Template, integrated cleanly, and adapted to the product’s domain, with the template's demo route prefixes flattened to the product's own layout (for example,
/login, not/auth/auth1/login). - The frontend bundle contains no hardcoded backend scheme/host/port; the API base URL resolves from
window.location.originat runtime, with an empty-string SSR fallback that produces relative URLs (Section 6.2.1). - Every administrative
/api/v1route is protected by the authenticated-group middleware (Section 8.5); the public allowlist is limited to version, health, login, logout, CSRF, and OIDC endpoints, and is logged at startup. - On a fresh data directory, the binary seeds an initial
adminuser via the bootstrap flow (Section 8.6), usingORCHESTRAD_BOOTSTRAP_PASSWORD/_FILEwhen provided and otherwise defaulting toadmin/adminwithpassword_reset_requiredset, so the first login is forced through the/change-passwordflow defined in Section 8.8. - Trusted-proxy middleware (Section 8.7) is wired in front of auth, authorization, and audit;
ORCHESTRAD_TRUSTED_PROXIESis empty by default andX-Forwarded-*headers are ignored from untrusted peers. - Every secret-bearing environment variable accepts the
_FILEcompanion form (Section 9.1) and the config loader trims trailing whitespace/newlines from file-backed values. - CORS defaults to an empty allowlist in the embedded-UI deployment and is only populated when
ORCHESTRAD_ALLOWED_ORIGINSis explicitly set. - Logs follow the format
[TimestampUTC] - [Component] - [Level] - Messagefor standard logs. - Error logs include
[File:Line:Column]and remain human-readable without excessive stack trace noise. - Dashboard and run history are visible.
- Logs rotate automatically with retention cleanup.
- Audit trail exists for all sensitive actions.
- Code is modular and centralized with no obvious business-logic duplication.
- The UI delivery model honors the
embed_ui_in_binaryquestion in Section 2.3. For the default answer (yes), the released binary serves the full UI from its own HTTP server via//go:embed, with SPA fallback for deep links and no dependency on a separate web server, Node.js runtime, or static host.
32. Recommended Future Enhancements
- multi-tenant logical partitioning
- directory synchronization across multiple forests
- approval workflows for destructive actions
- reusable condition/action templates
- simulation snapshots and compare views
- metrics exporter
- webhooks / notifications
- attribute transformation pipelines
- policy-as-code export/import
33. Final Product Positioning
This product should be understood as:
A modern, secure, database-backed, API-first Active Directory automation platform that begins with dynamic group automation but grows into a generalized directory rule engine with strong operational visibility, maintainability, and a much better administrator experience than JSON-driven legacy tools.