Gitly delegates the network protocol, host keys, ciphers, rate limiting, and connection lifecycle to the operating system's OpenSSH server. Gitly owns repository authorization and runs git-upload-pack or git-receive-pack through restricted forced commands. This follows the same user-facing key and deploy-key concepts documented by GitLab for SSH access and deploy keys.
- Create a dedicated operating-system account such as
git. Do not give it an interactive password or administrative access. - Create its
.sshdirectory with mode0700andauthorized_keyswith mode0600. - Run Gitly as that account, or grant the Gitly process narrowly scoped write access to the configured
authorized_keysfile. OpenSSH must still accept the final ownership and mode. - Configure
GITLY_SSH_ENABLED,GITLY_SSH_HOSTNAME,GITLY_SSH_PORT,GITLY_SSH_USER, andGITLY_SSH_AUTHORIZED_KEYS_PATHas shown in the README. - Ensure the Gitly executable,
config.json, database, and repository storage paths remain available at the same absolute paths to forced-command processes. - Restart Gitly once. Startup migrations backfill key fingerprints and synchronize the managed key block.
Gitly preserves every line outside:
# BEGIN GITLY MANAGED KEYS
# END GITLY MANAGED KEYS
Do not manually edit inside that block. Authentication keys use OpenSSH's restrict option and a forced Gitly command, so port forwarding, agent forwarding, PTYs, arbitrary commands, and interactive shells are unavailable.
- Public repositories can be fetched by any active Gitly user key. Private repositories require Reporter or greater access.
- Push requires Developer or greater access and is checked again against protected-branch rules in a pre-receive hook.
- Protected branches cannot be deleted or force-pushed. Their configured role threshold applies to SSH just as it does to HTTP.
- Deploy keys are scoped to one repository. They are read-only unless a Maintainer explicitly enables write access. Write keys run with Developer access by default; pushing a branch protected above Developer requires the separate protected-branch grant.
- Expired, disabled, signing-only, duplicate, malformed, and blocked-user keys are not written to the managed block.
- Successful use updates the key's
last_used_atvalue.
The post-receive hook refreshes repository caches, invalidates merge-request approvals for changed heads, triggers configured CI, and starts push mirrors.
Use ssh -T git@git.example.com to verify that interactive access is rejected. Then clone an allowed repository with the SSH URL shown in its Code menu. OpenSSH logs remain the authoritative source for handshake and host-key failures; Gitly's security and application logs cover account/repository authorization failures.