Home / Alt manpages / git-credential(1)

  • git-credential(1)
  • User command
  • linux

Script Git Logins with git credential

Your deploy script needs a Git password, and hard-coding it in the script is how tokens end up on the internet. In about fifteen minutes you will build a scriptable workflow with git credential: describe a remote, ask a configured helper for credentials, and approve or reject the result. The examples use Git 2.43.0, the version installed on this machine. You need Git and a shell, and no elevated privileges.

Security boundary

Credentials are secrets. The examples use example.com and a throwaway token. Do not paste a real password into shell history, a ticket or an article. A helper may store whatever you approve, so inspect its configuration before you send it anything.

1. Understand the three actions

git credential is an interface for programs that want Git's normal credential lookup. It reads a credential description from standard input. The action is one of fill, approve or reject:

  • fill asks. It consults configuration, helpers and possibly the user for a username and password, then prints the completed description.
  • approve vouches. It tells configured helpers the credential worked, so they may store or reuse it.
  • reject retracts. It tells configured helpers the credential failed, so they may erase a matching entry.

approve and reject normally print nothing. The command never contacts the remote server itself. Your application must use the returned credential, decide whether authentication succeeded, and then report that result.

2. Feed a complete description

Each attribute is one key=value line. End the input with a blank line or end-of-file. For an HTTPS repository, the useful identifying fields are usually the protocol, host and path:

$ printf '%s\n' \\
    'protocol=https' \\
    'host=example.com' \\
    'path=team/project.git' \\
    ''
  • The blank line is not decoration. It terminates the description.
  • No newlines or NULs in values. There is no quoting or escaping layer.
  • Ports live in the host. Write example.com:8443 when one is present.

You can hand over a URL instead of splitting it yourself. The URL must include a protocol:

$ printf '%s\n' 'url=https://example.com/team/project.git' ''

Git parses that special attribute into the matching credential fields. An unrecognised attribute is silently discarded, so check your spelling. Never put a password in a URL used for diagnostics or logs.

3. Retrieve a credential with fill

Ask the configured helpers for a credential, and capture the output only where your program can protect it:

$ printf '%s\n' \\
    'protocol=https' \\
    'host=example.com' \\
    'path=team/project.git' \\
    '' | git credential fill
protocol=https
host=example.com
username=guide-user
password=guide-token

The username and password depend on your helper, so the values above are illustrative. A helper might already hold a credential, or Git might prompt on the terminal. In a non-interactive program, decide deliberately whether prompting is acceptable, and treat a non-zero exit status as a failed lookup.

Tip

Watch the path default. For HTTP and HTTPS, Git may drop path when credential.useHttpPath is false, so one credential covers a whole host. If separate repositories on the same host need separate credentials, check this setting before you rely on the path as a boundary:

$ git config --show-origin --get credential.useHttpPath

No output means the setting is not explicitly configured in the places Git searched. The effective default for HTTP(S) is false. Change it only after checking how your existing helper stores credentials.

4. Approve only a credential that worked

Once your application has authenticated to the remote, send the completed description to approve. Include the username and password that fill returned, not just the original lookup fields:

$ printf '%s\n' \\
    'protocol=https' \\
    'host=example.com' \\
    'path=team/project.git' \\
    'username=guide-user' \\
    'password=guide-token' \\
    '' | git credential approve

There should be no normal output. This command can change state in a configured helper, including writing a credential to a file or keychain. It does not grant access to the repository and does not verify the token.

Warning

Approving before the remote has accepted the credential can preserve a bad secret and cause repeated failures.

5. Reject a credential that failed

If the remote refused the credential, pass the same completed description to reject:

$ printf '%s\n' \\
    'protocol=https' \\
    'host=example.com' \\
    'path=team/project.git' \\
    'username=guide-user' \\
    'password=guide-token' \\
    '' | git credential reject

Expect no output again. Helpers decide how to erase a matching credential, and rejection does not guarantee every copy has vanished, particularly when several helpers are configured. Check the helper documentation if you need deletion guarantees.

Recovery

If you approved a test or compromised credential, reject it immediately and rotate it with the service that issued it. Removing a local helper file alone does not invalidate a token already sent to a remote service or copied into a keychain backup.

6. Test a helper without touching your real store

For a repeatable smoke test, point Git's temporary configuration at a throwaway store under /tmp. The store helper is used here only to demonstrate the protocol:

$ helper_file=$(mktemp /tmp/git-credential-demo.XXXXXX)
$ chmod 600 "$helper_file"
$ printf '%s\n' \\
    'protocol=https' 'host=example.com' \\
    'username=guide-user' 'password=guide-token' '' |
    git -c credential.helper="store --file=$helper_file" credential approve
$ printf '%s\n' 'protocol=https' 'host=example.com' '' |
    git -c credential.helper="store --file=$helper_file" credential fill
protocol=https
host=example.com
username=guide-user
password=guide-token
$ printf '%s\n' \\
    'protocol=https' 'host=example.com' \\
    'username=guide-user' 'password=guide-token' '' |
    git -c credential.helper="store --file=$helper_file" credential reject

The temporary file sits deliberately outside your normal Git configuration. The chmod keeps other users out while it exists, but it is still a plain-text test store. Inspect it if you need to verify the test, then remove it when finished:

$ test ! -s "$helper_file" && echo 'test credential removed'
$ rm -- "$helper_file"

Warning

The final rm deletes that temporary file for good, though it does not touch a repository. Do not substitute a path from your real credential configuration.

7. Keep scripts from leaking secrets

  • No tracing. Do not enable shell tracing around fill.
  • No routine dumps. Do not print the complete response for ordinary logging.
  • Protect the password. Keep it in a protected variable or pipe, clear temporary files promptly, and pass only the fields the helper needs.
  • Refresh tokens are secret too. oauth_refresh_token is confidential. Git treats it as helper data and applies no special logic to it, while it does recognise password_expiry_utc for expired generated passwords.

Use a non-zero result to stop a deployment when fill cannot return a usable credential. Keep the three outcomes separate: lookup failed, authentication failed, authentication succeeded. Only the last one merits approve.

Done means

  • Input is well formed. The script sends a terminated attribute list with the correct protocol and host.
  • Output is treated as secret. fill output is never copied into logs.
  • Approval is earned. approve is sent only after the remote accepts the credential.
  • Failure is reported. reject is sent after an authentication failure, with rotation for exposed credentials.
  • Scope matches intent. Helper scope, especially the HTTP(S) path default, fits the access boundary you meant.