---
name: "git-annex-shell"
section: "1"
platform: "linux"
package: "git-annex"
version: "10.20261026-1"
release: "Arch Linux 2026-11-01"
platforms: ["linux"]
url: "https://new.carta.tech/git-annex-shell"
---

# git-annex-shell(1)

Restricted login shell for git-annex only SSH access

## NAME

git-annex-shell - Restricted login shell for git-annex only SSH access

## SYNOPSIS

git-annex-shell \[-c\] command \[params ...\]

## DESCRIPTION

git-annex-shell is a restricted shell, similar to git-shell, which can be used as a login shell for SSH accounts.

Since its syntax is identical to git-shell's, it can be used as a drop-in replacement anywhere git-shell is used. For example it can be used as a  user's restricted login shell.

## COMMANDS

Any command not listed below is passed through to git-shell.

Note that the directory parameter should be an absolute path, otherwise it is assumed to be relative to the user's home directory. Also the first "/~/" or "/~user/" is expanded to the specified home directory.

- configlist directory

  This outputs a subset of the git configuration, in the same form as **git config --list**. This is used to get the annex.uuid of the remote repository.

-

  When run in a repository that does not yet have an annex.uuid, one will be created, as long as a git-annex branch has already been pushed to the repository, or if the autoinit=1 flag is used to indicate initialization is desired.

-

  - p2pstdio directory uuid

  This causes git-annex-shell to communicate using the git-annex p2p protocol over stdio.

-

  The uuid is the one belonging to the repository that will be communicating with git-annex-shell.

-

  - notifychanges directory

  This is used by **git-annex remotedaemon** to be notified when refs in the remote repository are changed.

-

  - gcryptsetup directory gcryptid

  Sets up a repository as a gcrypt repository.

-

  - inannex directory \[key ...\]

  This checks if all specified keys are present in the annex,  and exits zero if so.

-

  Exits 1 if the key is certainly not present in the annex. Exits 100 if it's unable to tell (perhaps the key is in the process of being removed from the annex).

-

  Used only by the gcrypt special remote.

-

  - recvkey directory key

  This runs rsync in server mode to receive the content of a key, and stores the content in the annex.

-

  Used only by the gcrypt special remote.

-

  - sendkey directory key

  This runs rsync in server mode to transfer out the content of a key.

-

  Used only by the gcrypt special remote.

-

  - dropkey directory \[key ...\]

  This drops the annexed data for the specified keys.

-

  Used only by the gcrypt special remote.

-

  ## OPTIONS

- \--uuid=UUID

  -

  git-annex uses this to specify the UUID of the repository it was expecting git-annex-shell to access. This is both a sanity check, and allows git-annex shell to proxy access to remotes, when configured by git-annex-update-proxy.

-

  - Also the [git-annex-common-options(1)](/git-annex-common-options/1.md) can be used.

  - \-- fields=val fields=val.. --

  Additional fields may be specified this way, to retain compatibility with past versions of git-annex-shell (that ignore these, but would choke on new dashed options).

-

  Currently used fields are autoinit= and remoteuuid=

-

  ## HOOK

After content is received or dropped from the repository by git-annex-shell, it runs a hook, **.git/hooks/annex-content** (or **hooks/annex-content** on a bare repository). The hook is not currently passed any information about what changed.

## ENVIRONMENT

- GIT\_ANNEX\_SHELL\_READONLY

  -

  If set, disallows any action that could modify the git-annex  repository.

-

  Note that this does not prevent passing commands on to git-shell. For that, you also need ...

-

  - GIT\_ANNEX\_SHELL\_LIMITED

  If set, disallows running git-shell to handle unknown commands.

-

  - GIT\_ANNEX\_SHELL\_APPENDONLY

  If set, allows data to be written to the git-annex repository, but does not allow data to be removed from it.

-

  Note that this does not prevent passing commands on to git-shell, so you will have to separately configure git to reject pushes that overwrite branches or are otherwise not appends. The git pre-receive hook may be useful for accomplishing this.

-

  It's a good idea to enable annex.securehashesonly in a repository that's set up this way.

-

  - GIT\_ANNEX\_SHELL\_DIRECTORY

  If set, git-annex-shell will refuse to run commands that do not operate on the specified directory.

-

  ## EXAMPLES

To make a **~/.ssh/authorized\_keys** file that only allows git-annex-shell to be run, and not other commands, pass the original command to the -c option:

 command="git-annex-shell -c \\"$SSH\_ORIGINAL\_COMMAND\\"",no-agent-forwarding,no-port-forwarding,no-X11-forwarding ssh-rsa AAAAB3NzaC1y\[...\] user@example.com

To further restrict git-annex-shell to a particular repository,  and fully lock it down to read-only mode:

 command="GIT\_ANNEX\_SHELL\_DIRECTORY=/srv/annex GIT\_ANNEX\_SHELL\_LIMITED=true GIT\_ANNEX\_SHELL\_READONLY=true git-annex-shell -c \\"$SSH\_ORIGINAL\_COMMAND\\"",restrict ssh-rsa AAAAB3NzaC1y\[...\] user@example.com

Obviously, **ssh-rsa AAAAB3NzaC1y\[...\] user@example.com** needs to replaced with your SSH key. The above also assumes **git-annex-shell** is available in your **$PATH**, use an absolute path if it is not the case. Also note how the above uses the **restrict** option instead of an explicit list of functionality to disallow. This only works in certain OpenSSH releases, starting from 7.1p2.

To only allow adding new objects to the repository, the **GIT\_ANNEX\_SHELL\_APPENDONLY** variable can be used as well:

command="GIT\_ANNEX\_SHELL\_DIRECTORY=/srv/annex GIT\_ANNEX\_SHELL\_APPENDONLY=true git-annex-shell -c \\"$SSH\_ORIGINAL\_COMMAND\\"",restrict ssh-rsa AAAAB3NzaC1y\[...\] user@example.com

This will not keep an attacker from destroying the git history, as explained above. For this you might want to disallow certain operations, like branch deletion and force-push, with options from [git-config(1)](/git-config/1.md). For example:

git config receive.denyDeletes true git config receive.denyNonFastForwards true

With this configuration, git commits can still remove files,  but they will still be available in the git history and git-annex will retain their contents. Changes to **git-annex** branch, however, can negatively impact git-annex's location tracking information and might cause data loss. To work around this problem, more complex hooks are required, see for example the **update-paranoid** hook in the git source distribution.

## SEE ALSO

[git-annex(1)](/git-annex/1.md)

[git-shell(1)](/git-shell/1.md)

## AUTHOR

Joey Hess \<id@joeyh.name\>

\<http://git-annex.branchable.com/\>
