Documentation
Git access control and grants
Everlock uses a path-based grant system to control who can read from and push to repositories. Every access decision — clone, push, admin action — is checked against a table of grants attached to users and groups. This page explains the model, the commands, and common patterns for sharing repositories across a team.
The three roles
Every grant assigns one of three roles:
| Role | Can clone (read) | Can push (write) | Can delete |
|---|---|---|---|
reader | Yes | No | No |
writer | Yes | Yes | No |
owner | Yes | Yes | Yes |
Roles are ordered: owner implies writer, writer implies reader. Assigning owner to a user gives them all three capabilities.
When you create a repository with /git create, you automatically become its owner.
When /site create creates a site, it automatically grants the creating user writer access to the underlying store.
The access path format
Every grant is scoped to an access path with exactly three segments:
frontend / backend / namespace
| Segment | Meaning | Example values |
|---|---|---|
frontend | The protocol the request arrives on | ssh, http, * |
backend | The backend family | git, site, * |
namespace | The specific resource | my-repo, * |
Any segment can be * to match all values of that segment:
ssh/git/my-repo — my-repo over SSH only
*/git/my-repo — my-repo over any frontend
ssh/git/* — all repos over SSH
*/*/* — everything (system owner)
Which path to use when granting repository access
For Git repositories, */git/<name> is the right pattern in almost all cases. It covers SSH today and HTTP when it becomes available, so you do not have to update grants when a new frontend is added:
/users grant alice */git/my-project writer
Use ssh/git/<name> only when you deliberately want to restrict access to a specific frontend and deny it on others.
Granting access to a user
/users grant <login> <path> <role>
Examples:
/users grant alice */git/my-project reader
/users grant bob */git/my-project writer
/users grant carol */git/my-project owner
Grants take effect immediately — no restart required. The user can clone or push as soon as the grant is recorded.
Granting access to all repositories
To give a user access to every repository (for example, a CI account that needs to clone everything):
/users grant ci-bot ssh/git/* reader
This grants ci-bot read access to every repository over SSH. Combined with a writer grant on a specific repo:
/users grant ci-bot */git/deploy-config writer
The user picks up the highest matching role for any given path.
Revoking access
/users revoke <login> <path>
Example:
/users revoke alice */git/my-project
This removes the specific grant. If the user has other grants that still match the path (for example via a group), those remain in effect.
Inspecting a user's grants
/users grants alice
Expected output shape:
alice
grant: */git/my-project writer
grant: */git/config reader
This shows every explicit grant on the user, useful for auditing before adding or removing access.
Groups
Groups let you grant access to multiple users at once. Any user in the group inherits the group's grants. This is the right model for teams — grant the group, then add and remove members without touching individual grants.
Creating a group and adding members
There is no explicit /groups create command. A group is created implicitly the first time it appears in a grant. Members are added via user management (see the user model documentation).
Granting a group access to a repository
/groups grant <group-name> <path> <role>
Example — grant the backend-team group writer access to two repositories:
/groups grant backend-team */git/api-service writer
/groups grant backend-team */git/shared-lib writer
Every user who is a member of backend-team can now push to both repositories.
Revoking a group grant
/groups revoke backend-team */git/shared-lib
Removes the group grant. Individual user grants on the same path are not affected.
Full example: a shared project with a team
Here is a complete walkthrough for setting up a shared repository with different access levels for different people.
1. Create the repository
/git create api-docs
The admin who runs this command becomes owner automatically.
2. Add users
/users add alice password-for-alice
/users add bob password-for-bob
/users add carol password-for-carol
3. Grant individual access
Alice is a core contributor — give her write access:
/users grant alice */git/api-docs writer
Bob only needs to read the docs — give him read access:
/users grant bob */git/api-docs reader
Carol is co-maintaining the repo — give her ownership:
/users grant carol */git/api-docs owner
4. Each user clones with their own credentials
# Alice
git clone ssh://alice@localhost:2222/api-docs
# Bob
git clone ssh://bob@localhost:2222/api-docs
# Carol
git clone ssh://carol@localhost:2222/api-docs
Alice and Carol can push. Bob can only clone.
5. Using a group for the writing team
As the project grows, adding individual grants for each new writer becomes tedious. Move to a group:
/groups grant writers-team */git/api-docs writer
Now any user added to writers-team automatically gets write access. Individual explicit grants can be left in place or revoked — a user's effective role is the highest role from any matching grant (individual or group).
How grants interact with site stores
When /site create runs, it automatically records a grant like this:
alice */git/my-site writer
That is the grant that lets the site creator push content. It works exactly like a manually created grant. You can view it with /users grants alice, extend it to other users with /users grant, and revoke it the same way.
The site backend reads content directly from the repository's HEAD. Access control on the HTTP serving side (public vs authenticated) is a separate setting on the site entry, not a Git grant. Git grants only govern who can push and pull over SSH.