FreeSelf-hostedWritten in Go
One repository.
Not everybody sees
all of it.
nit sits between your developers and your forge and decides, per file, who may read and who may write. Nobody splits the repository. Nobody maintains a second copy with the secrets taken out.
No key to buy, no seat to count, no clock.
src/server/ and may not write it; he may read and write src/ui/. Two paths never leave the forge. The tree he gets builds — it is a working tree, not a redacted copy of one.Rules: configs/policy/example/repositories/backend-api/rules.yaml01 The problem
Git has one answer to “can this person see that file”, and the answer is the repository.
So teams do one of three things, and all three are worse than the thing they are working around.
Split it
Two repositories that share a build, a history and a set of people who now have to remember which one a change belongs in.
Mirror it
A second copy with the sensitive directories stripped, and a job that keeps it in step. Every drift between the two is a bug nobody sees.
Write a policy
Access to everything, and a document saying not to look. The common one — and the one you cannot describe to an auditor with a straight face.
02 Where the decision lives
A rule you can read, and an answer you can ask for.
YAML in the repository, reviewed in a pull request. Deny wins over allow whatever the order, and anything unmatched is denied.
You never have to guess what the rules add up to. nitctl policy explain answers for one person, one path, one repository, and names the rule.
# Nobody outside the platform team may even read these.
# Because the deny covers read, the files never appear in
# anyone else's workspace at all.
- id: secrets-are-platform-only
subject:
type: any
except:
- type: group
id: platform
paths:
- secrets/
- infra/production/
actions: [read, write, create, delete, admin]
effect: deny$ nitctl policy explain -repo backend-api \
-user bob -path secrets/prod.key
bob on secrets/prod.key (backend-api)
groups: frontend
DENY read denied by rule secrets-are-platform-only
(denied_by_rule: secrets/)03 What that changes
A contractor clones the repository
They get the files they may read, and it builds. Not a warning, not a redacted file — what they may not read is not in what they received.
Somebody pushes where they should not
Refused at the boundary, naming the rule that refused it. Not a review comment three days later.
The rules are a file in the repository
Reviewed in a pull request. Who changed a permission, and when, is the same question as who changed any other line.
Your forge stays your forge
GitHub, GitLab, Gitea. nit is in front of it, not instead of it. Take nit away and your repository is still a git repository.
04 The enterprise edition
If somebody outside your company will ask you to prove it.
nit records its own decisions, in your own database. That is enough for almost everybody.
It stops being enough when the person asking is an auditor, a regulator or a court — somebody who cannot take “our logs say so” from the party the question is about. The audit vault keeps those decisions in a separate system that cannot forge one, each signed by a key that never leaves your control plane.
It is licensed, and it runs on your own infrastructure like everything else here.