Home / Alt manpages / git-credential(1)

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

Use git-credential Safely in Scripts and Credential Helpers

You will finish with a scriptable Git credential workflow: describe a remote, ask a configured helper for credentials, report whether a request succeeded, and approve or reject the result. The examples use Git 2.43.0, the version installed on this machine. Allow about fifteen minutes. You need Git and a shell; no elevated privileges are required.

Security boundary

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

1. Understand the three actions

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

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

approve and reject normally produce no output. The command does not contact 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 with 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. Values cannot contain a newline or NUL, and there is no quoting or escaping layer. The host includes a port when one is present, such as example.com:8443.

You can provide 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 corresponding credential fields. An unrecognised attribute is silently discarded, so check spelling carefully. Do not 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 exact username and password depend on your helper, so the values above are illustrative. A helper might already have a credential, or Git might prompt through the terminal. In a non-interactive program, decide deliberately whether prompting is acceptable and handle a non-zero exit status as a failed lookup.

One confusing default concerns the path. For HTTP and HTTPS, Git may remove path when credential.useHttpPath is false. That makes one credential apply more broadly to a host. If separate repositories on the same host must have separate credentials, review this setting before relying on the path as a boundary:

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

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

4. Approve only a credential that worked

After your application has successfully authenticated to the remote, send the completed description to approve. Include the username and password returned by fill, 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. Approving before the remote accepted the credential can preserve a bad secret and cause repeated failures.

5. Reject a credential that failed

If the remote rejected 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

Again, expect no output. Helpers decide how to erase a matching credential. Rejection is not a guarantee that 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 the credential 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 is deliberately outside your normal Git configuration. The chmod command protects it from other users 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"

The final rm is destructive for that temporary file, though it does not affect a repository. Do not substitute a path from your real credential configuration.

7. Keep scripts from leaking secrets

Do not enable shell tracing around fill, and do not print the complete response for routine logging. Keep the password in a protected variable or pipe, clear temporary files promptly, and pass only the fields the helper needs. Remember that oauth_refresh_token is confidential too. Git recognises password_expiry_utc for expired generated passwords, while it treats oauth_refresh_token as helper data rather than applying special logic to it.

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 and authentication succeeded. Only the last one merits approve.

Done means

  • The script sends a terminated attribute list containing the correct protocol and host.
  • fill output is handled as secret data and is not copied into logs.
  • approve is sent only after the remote accepts the credential.
  • reject is sent after authentication failure, with rotation for exposed credentials.
  • Helper scope, especially the HTTP(S) path default, matches the access boundary you intended.