Skip to content

Repository files navigation

IdentityLint

CI License: MIT

Make “wrong GitHub account” a failing check, not a post-push surprise.

IdentityLint compares four pieces of repository state against a reviewable policy:

  1. the effective Git author pair;
  2. whether that author is pinned in local repository config;
  3. each remote's expected host and owner;
  4. authors of an optional Git revision range;
  5. the GitHub account currently returned by gh.

It audits. It never switches accounts, reads tokens, edits Git config, or touches credentials.

$ identitylint check
PASS  GIT001     author is 0xacee <0xacee@users.noreply.github.com>
PASS  GIT002     author name and email are pinned locally
PASS  REMOTE001  origin targets github.com/0xacee
ERROR GH001      active GitHub account @work-user is not allowed

Identity boundary failed: 1 error, 0 warnings

Quick start

Node.js 20 or newer and Git are required. GitHub CLI is required only when the policy lists githubAccounts.

# Add a reproducible development dependency directly from GitHub
npm install --save-dev github:0xacee/identitylint

# Snapshot the current public identity labels into policy
npx identitylint init

# Audit locally or in automation
npx identitylint check
npx identitylint check --offline --strict

# Catch wrong-identity commits before pushing a branch
npx identitylint check --commits origin/main..HEAD

init creates .identitylint.json with wx semantics: it refuses to replace an existing policy. Review the generated file before committing it.

Policy

{
  "$schema": "https://raw.githubusercontent.com/0xacee/identitylint/main/schemas/policy.schema.json",
  "version": 1,
  "authors": [
    {
      "name": "0xacee",
      "email": "0xacee@users.noreply.github.com"
    }
  ],
  "requireLocalAuthor": true,
  "remotes": [
    {
      "name": "origin",
      "hosts": ["github.com"],
      "owners": ["0xacee"]
    },
    {
      "name": "upstream",
      "hosts": ["github.com"],
      "owners": ["Osmantic"]
    }
  ],
  "allowUnlistedRemotes": false,
  "githubAccounts": ["0xacee"]
}

Author names and emails are evaluated as pairs, so the name from one identity cannot accidentally be combined with another identity's email. GitHub hosts and owners are compared case-insensitively.

Commit hook

After installing IdentityLint in the repository:

npx identitylint hook install

The installer creates .git/hooks/pre-commit only when that path is unused. It never replaces or chains an existing hook. The hook runs an offline strict check, so a commit cannot depend on GitHub or network availability.

Automation and JSON

identitylint check --format json
identitylint check --offline --strict
identitylint check --commits '@{upstream}..HEAD'

--offline skips the gh probe and produces a warning when a GitHub account policy exists. Use it in isolated build jobs that do not carry user credentials. JSON contains identity labels and remote coordinates, never tokens or remote credentials.

Exit codes

Code Meaning
0 boundary holds (and no warnings under --strict)
1 policy mismatch
2 usage, policy, Git, or I/O error

Threat model

IdentityLint catches accidental cross-account attribution and remote mix-ups. It does not verify ownership of an email, authenticate a remote, validate signatures, sandbox Git hooks, or defend against a malicious local user. Those are deliberately left to Git, SSH/HTTPS credentials, and signed commits.

License

MIT

About

Policy-as-code guardrails for Git and GitHub account boundaries

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages