# 1. Download the production Compose manifest
$ curl -O https://raw.githubusercontent.com/uslanozan/Tidyorg/main/docker-compose.ghcr.yml
# 2. Scaffold your local config and state directories (first run only)
$ docker compose -f docker-compose.ghcr.yml run --rm engine scaffold
# 3. Drop your GitHub App private key at ./app.pem and configure environment variables
# (TF_VAR_github_org_name, TF_VAR_github_app_id, TF_VAR_github_app_installation_id)
# 4. Preview your infrastructure plan
$ docker compose -f docker-compose.ghcr.yml run --rm engine plan
# 5. Apply changes once the plan looks right
$ docker compose -f docker-compose.ghcr.yml run --rm engine apply
# 6. Launch the web dashboard on http://localhost:8080
$ docker compose -f docker-compose.ghcr.yml up -d dashboard
INFRASTRUCTURE AS CODE • OPEN SOURCE
Tidy Your Org Up.
The config-driven control plane for GitHub organizations. Describe repositories, teams, and branch protections in YAML; reconcile with Terraform. Every change is an audited pull request.
THE PROBLEM
Why managing GitHub through the UI fails as your team grows.
When teams expand, clicking through repository settings tabs creates invisible security vulnerabilities, unrecorded changes, and accidental privilege escalations.
Silent Configuration Drift
Someone disables branch protection temporarily to push a quick hotfix, but forgets to re-enable it. Two months later, main has had zero review requirements without anyone knowing.
Who Has Access to What?
Answering "which repos can contractor Jane access?" requires opening 50 different repository settings pages, team memberships, and collaborator tables. There is no single manifest.
Unrecorded ClickOps
Settings changes made in GitHub's web interface don't produce commits, PR discussions, or review records. When production breaks, nobody knows who changed the webhook or status check.
Accidental Org Owners
In standard GitHub setups, team leads frequently request Org Admin permissions merely to manage repository settings or invite teammates, completely violating least-privilege principles.
Rebuilding is Impossible
If your organization needs a staging clone, a migration, or disaster recovery, reproducing branch rules, labels, permissions, and webhook configurations by hand takes weeks of painful effort.
Patchwork Repo Rules
Some repos enforce 2 reviews; others enforce 0. Some delete branches on merge; others accumulate thousands of stale branches. Defaults set at the org level are easily bypassed.
The Tidyorg Rule: Anything changed by hand in the GitHub UI drifts back to the declared state on the next Terraform apply. The configuration is the only source of truth.
See Config Schema →INTERACTIVE DEMONSTRATION
Grounded in the real dashboard. Try it yourself.
The optional Tidyorg web dashboard lets team leads view and propose changes across the organization without touching Terraform code. Every edit becomes a Pull Request, and batch mode can combine several edits into one proposal.
payment-service Go
Core payment processing and Stripe reconciliation pipeline
Rules not specified in the repository file inherit from organization defaults.
| BRANCH | APPROVALS | CODEOWNERS | STATUS CHECK | FORCE PUSH | SOURCE |
|---|
Labels inherited from organization defaults. Repositories can define custom label sets.
Payment-Org-AI/config. It never talks to Terraform directly.
# Loading YAML...
# Loading Terraform Plan...
* Illustrative interactive demonstration based on the authentic Tidyorg v0.1.3 dashboard design system with fictional organization and member data.
HOW IT WORKS
From YAML declaration to GitHub reality.
A clear, auditable 5-step loop. Notice the strict boundary: the dashboard proposes pull requests; humans review; Terraform executes.
1. Declare
Describe repos, roles, and branch protections in YAML files under config/.
2. Propose
Use the dashboard or a git branch to open a Pull Request against the config repository.
Dashboard / Git3. Review
Peers and CODEOWNERS inspect the PR. CI executes terraform plan to preview changes.
4. Execute
On merge, terraform apply runs via your configured CI workflow or local container.
5. Reconcile
GitHub resources are adjusted to match. Any unauthorized UI changes are automatically reverted.
GitHub APICONFIG SCHEMA
Four clean files. Zero HCL to write.
Tidyorg splits configuration by ownership boundaries. Rules are bound to roles, not people. Click a file to inspect its structure.
Defines organization roles, permission mappings, global repo defaults, and public org profile.
One file per repository. Declares mentors, developers, viewers, branch protection, and CODEOWNERS.
Flat list of GitHub usernames that belong to the organization. Add or remove a user with a single line.
The escalation barrier: Org Owners and privileged roles. The dashboard does not generate edits for this CODEOWNERS-protected file.
Contract defining organization roles, base permissions, global defaults, team names, and public organization profile.
# config/organization.yml
version: 1
organization: Payment-Org-AI
# ROLES — Permission definitions bound to roles, not individual people
roles:
head-of-engineering:
scope: organization
repo_permission: admin
mentor:
scope: repository
repo_permission: admin
developer:
scope: repository
repo_permission: push
viewer:
scope: repository
repo_permission: pull
# Defaults applied to all repositories unless overridden
defaults:
visibility: private
has_issues: true
delete_branch_on_merge: true
branch_protection:
required_reviews: 2
require_code_owner_review: true
require_status_checks:
- ci/test
profile:
name: "Payment-Org-AI"
description: "Declarative infrastructure for Payment-Org-AI"
LEAST PRIVILEGE BY DESIGN
Two GitHub Apps. Zero shared secrets.
Tidyorg authenticates strictly through GitHub Apps using short-lived tokens. No personal access tokens (PATs) or employee credentials are ever stored.
tidyorg-engine-bot Installed on Org
Used by Terraform Reconciliation RunnerBroad permissions because it reconciles the entire organization against the configuration:
- Organization → AdministrationRead & Write
- Organization → MembersRead & Write
- Repository → AdministrationRead & Write
- Repository → Contents, Issues & WorkflowsRead & Write
- Repository → MetadataRead-only
tidyorg-dashboard-app Single Repo Only
Installed ONLY onPayment-Org-AI/config
Deliberately narrow scopes. Only opens PRs on the signed-in user's behalf via Device Flow:
- Repository → Contents (Config branch only)Read & Write
- Repository → Pull RequestsRead & Write
- Repository → Actions (Live sync status badge)Read-only
- Repository → MetadataRead-only
When users log in via GitHub Device Flow, their membership and role are evaluated immediately:
- Non-organization members: Displayed an instant
Access Deniedscreen (AccessDenied). No repositories, members, or settings are readable. - Non-mentors on a repository: The dashboard loads in Read-Only mode. Buttons to add members, edit repository settings, or archive are hidden/disabled.
- GitHub-level enforcement: Write access to proposal branches requires membership in the
tidyorg-dashboard-writersteam. Direct API tampering will be rejected by GitHub's branch protection.
GET STARTED
Deploy in minutes with Docker.
Pre-built multi-architecture images are published to both GitHub Packages (GHCR) and Docker Hub. No cloning or local compilation required.
# Pull from canonical GHCR Registry:
$ docker pull ghcr.io/uslanozan/tidyorg:0.1.3
$ docker pull ghcr.io/uslanozan/tidyorg-dashboard:0.1.3
# Or pull from automated Docker Hub mirror:
$ docker pull uslanozan/tidyorg:0.1.3
$ docker pull uslanozan/tidyorg-dashboard:0.1.3
# Run plan directly:
$ docker run --rm \
-v "$PWD/config:/config" \
-v "$PWD/state:/state" \
-v "$PWD/app.pem:/secrets/app.pem:ro" \
-e TF_VAR_github_org_name=Payment-Org-AI \
-e TF_VAR_github_app_id=123456 \
-e TF_VAR_github_app_installation_id=12345678 \
ghcr.io/uslanozan/tidyorg:0.1.3 plan
# HCP Terraform (Terraform Cloud) Remote State:
$ docker run --rm \
-v "$PWD/config:/config" \
-v "$PWD/app.pem:/secrets/app.pem:ro" \
-e TF_STATE=hcp \
-e TF_CLOUD_ORGANIZATION=your-tf-org \
-e TF_WORKSPACE=tidyorg-prod \
-e TF_TOKEN_app_terraform_io=your-token \
-e TF_VAR_github_org_name=Payment-Org-AI \
-e TF_VAR_github_app_id=123456 \
-e TF_VAR_github_app_installation_id=12345678 \
ghcr.io/uslanozan/tidyorg:0.1.3 plan
TRANSPARENCY
Project status & honest limitations.
We believe in technical credibility over marketing hype. Here is an exact assessment of where Tidyorg stands today.
Current Status: v0.1.3 (Pre-1.0)
- Functional Engine & Dashboard: Both Docker images are actively built, multi-arch tested (amd64, arm64), and available on GHCR & Docker Hub.
- Verified Pilot Run: Tested end-to-end against a fresh disposable GitHub organization: initial scaffold, initial apply, dashboard change proposal, PR merge, reconciliation, and clean zero-diff plan.
- Pre-1.0 Roadmap: Automated browser E2E test suites and fully disposable CI organization automation are ongoing before tagging 1.0.
⚠️ Known Limitations to Consider
- No Built-in Code Backup: Tidyorg manages infrastructure and authorization configuration; it does not back up git commit history or PR discussion metadata. Maintain your own off-GitHub backups.
- GitHub Free Plan Constraints: GitHub Free organizations cannot enforce branch protection rules on private repositories. Tidyorg surfaces this condition cleanly, but cannot override GitHub licensing.
- Non-Readable Settings Drift: Certain organization settings (such as billing email and PAT security policy) are write-only or unreadable via the GitHub API. Tidyorg treats the YAML config as ground truth for these fields.
QUESTIONS & ANSWERS
Frequently asked questions.
Need more details? Check the Technical Documentation →
What if I delete a repository by mistake?
Tidyorg is engineered with strict safeguards against accidental deletion:
1. No Hard Delete in the Dashboard: The web dashboard deliberately has no delete repository button. The most a mentor can do is archive a repository (archived: true), which freezes it as read-only while preserving all code, commit history, issues, and PR discussions.
2. Engine prevent_destroy Lock: The Terraform engine has a prevent_destroy lifecycle lock on repository resources. If a repository's YAML file is accidentally deleted from git, terraform apply will intentionally fail with an error rather than destroy the repository.
3. Deliberate Deletion Procedure: Truly deleting a repository requires intentional multi-step administrative action: removing the YAML file via reviewed PR, a platform admin manually executing terraform state rm, and then running the dedicated repository deletion script from the engine repository.
What do unauthorized users see when they log into the dashboard?
If a user authenticates via GitHub Device Flow:
• Non-members: If the user is not a member of the organization, they are immediately presented with an Access Denied screen. No repositories, members, or settings are disclosed.
• Non-mentors on a repo: If the user belongs to the org but is only a developer or viewer on a specific repository, the dashboard opens in strictly Read-Only mode. Buttons to add members, change branch protections, or archive are hidden/disabled.
Does the dashboard apply Terraform directly?
No. The dashboard does not talk to Terraform or execute applies directly. Instead, every change you make in the dashboard is batched into a standard GitHub Pull Request against your config repository. This guarantees that team review, CI status checks, and CODEOWNERS approvals are strictly honored before anything is applied.
What happens if someone changes a setting in the GitHub UI?
The next time Terraform runs (via CI or scheduled container apply), it will detect the drift and revert the manual change back to match your YAML configuration. The YAML files are the sole source of truth.
Where is the Terraform state stored?
By default, state is kept in the mounted ./state volume on your host, requiring zero external setup. For distributed teams, you can set TF_STATE=hcp to use HCP Terraform (Terraform Cloud) or configure a custom remote backend like AWS S3 or Google Cloud Storage.
Can anyone use the dashboard to make themselves an Org Owner?
No. The dashboard is installed only on the configuration repository, and its UI and proposal service never generate edits for config/privileged.yml. Organization Owners and admin roles remain isolated in that file, while CODEOWNERS and branch protection require administrator review before privileged changes can be merged.
Do I need to clone the repository to use Tidyorg?
No. The published Docker images (ghcr.io/uslanozan/tidyorg:0.1.3 and uslanozan/tidyorg:0.1.3) include the Terraform engine, provider dependencies, and starter configuration. You only need Docker and your GitHub App credentials.
INFRASTRUCTURE AS CODE
Bring order to your GitHub organization.
Replace fragile UI clicks with versioned, auditable, declarative configuration. Try the pre-built container or explore the open source repository.