umgr
umgr is a declarative account lifecycle tool for managing user account state
across platforms with a desired-state workflow.
You declare desired state in a YAML or JSON configuration file, and umgr
compares it with tracked current state to detect drift, import current users,
and generate/apply changes.
Motivation
Organizations often need to keep user accounts consistent across many systems.
umgr provides one interface to define account intent and reconcile drift.
Examples of platforms include Google Workspace, Atlassian, GitHub, Slack, AWS, Azure, and Sentry. This list is illustrative, not exhaustive.
Interfaces
umgr exposes two interfaces:
- CLI for operators (built with Thor)
- Ruby gem API for embedding in larger applications
Core Capabilities
- Drift detection between desired state and platform/user reality.
- Import of current users from providers/plugins as a baseline state.
- Declarative plan/apply workflow for account lifecycle changes.
Provider/Plugin Model
Each platform integration is implemented as a provider/plugin.
- Providers implement platform-specific sync logic with SDKs or REST APIs.
- Providers can expose additional provider-specific options on top of the core interface.
- The first built-in test provider is
echo, which returns a fake user account by echoing configured attributes.
Provider authoring guide:
docs/provider-authoring.md
DSL compile guide:
docs/dsl-compile.md
Website:
- Site entrypoint:
docs/index.html - Local preview/edit guide:
docs/website.md
Configuration and State
- Configuration formats: YAML and JSON
- Model: desired state (config) + current state reference (tool-managed state)
- Core identity convention:
provider.type.name
CLI Example
umgr init
umgr validate --config examples/users.yml
umgr plan --config examples/users.yml
umgr apply --config examples/users.yml
umgr showDSL Compile Workflow
umgr.rb is compile-time input only. Runtime commands (validate, plan,
apply, import) consume YAML/JSON config, not DSL source directly.
Assignment-only DSL shape:
umgr do
version = 1
end
resource "echo.user", "alice" do
team = "platform"
endumgr compile > umgr.yml
umgr plan --config umgr.ymlPipeline mode:
umgr compile | umgr plan --config -
umgr compile | umgr apply --config -Exhaustive configuration examples for umgr.rb, umgr.yml/umgr.yaml, and
umgr.json, plus error notes:
docs/dsl-compile.md
Ruby API Example
require "umgr"
runner = Umgr::Runner.new
result = runner.dispatch(:plan, config: "examples/users.yml")
puts result[:ok]
puts result.dig(:changeset, :summary)Private Installation (GitHub Packages)
umgr pre-releases are published to GitHub Packages (rubygems).
- Create a GitHub token with:
read:packages-
repo(required when the package repository is private)
- Configure RubyGems credentials:
mkdir -p ~/.gem
cat > ~/.gem/credentials <<'EOF'
---
:github: Bearer <YOUR_GITHUB_TOKEN>
EOF
chmod 0600 ~/.gem/credentials- Install directly:
gem install umgr \
--source "https://rubygems.pkg.github.com/gowda" \
--key githubGemfile Usage (Private Package)
source "https://rubygems.org"
source "https://rubygems.pkg.github.com/gowda" do
gem "umgr"
endConfigure Bundler authentication for GitHub Packages:
bundle config set --global rubygems.pkg.github.com "<GITHUB_USERNAME>:<YOUR_GITHUB_TOKEN>"Public RubyGems Publishing (OIDC)
Stable releases are published to RubyGems via OIDC trusted publishing.
- Public gem:
https://rubygems.org/gems/umgr - Workflow:
.github/workflows/publish-rubygems.yml - Publishing details:
docs/release-rubygems.md