This macOS error occurs when Git tries to access credentials stored in Keychain but the system blocks the request because no user interaction is possible. This commonly happens in automated environments like CI/CD pipelines, SSH sessions, cron jobs, or when the Keychain is locked.
This error is specific to macOS and indicates that Git's credential helper attempted to access the macOS Keychain to retrieve stored credentials (like GitHub passwords or personal access tokens), but the Keychain refused the request because user interaction was not allowed. The macOS Keychain is a secure storage system that may require user confirmation (clicking "Allow" in a dialog) before releasing stored credentials to an application. When Git runs in a non-interactive contextโsuch as a CI/CD pipeline, a cron job, an SSH session without a GUI, or a background processโthere's no way for the user to click "Allow" in a dialog box. The Keychain then returns this "User interaction is not allowed" error. This error can also occur when the Keychain is locked (for example, after a system restart before the user logs in via the GUI), or when running scripts that spawn Git processes in environments where the Security framework cannot display UI prompts.
First, understand why user interaction is not available. This error typically occurs in:
Non-interactive environments:
- CI/CD pipelines (GitHub Actions, Jenkins, CircleCI on macOS)
- SSH sessions without GUI
- Cron jobs or launchd services
- Background processes or daemons
Check if you're in an interactive session:
# Check if a display is available
echo $DISPLAY
# Check if running in a terminal
tty
# Check the session type
echo $TERM_PROGRAMIf you're in an interactive Terminal session but still seeing this error, the Keychain might be locked or the ACL is requiring confirmation.
If the Keychain is locked, you need to unlock it:
Unlock interactively:
# Unlock the login keychain
security unlock-keychain ~/Library/Keychains/login.keychain-db
# You'll be prompted for your macOS passwordUnlock with password (for scripts - use carefully):
# Unlock with password passed via stdin (more secure)
security unlock-keychain -p "$(cat /path/to/secure/password-file)" ~/Library/Keychains/login.keychain-db
# Or set password in environment variable (less secure, for CI only)
security unlock-keychain -p "$KEYCHAIN_PASSWORD" ~/Library/Keychains/login.keychain-dbCheck Keychain status:
# Show Keychain info
security show-keychain-info ~/Library/Keychains/login.keychain-dbImportant: Never commit passwords or store them in plain text. Use CI/CD secrets management.
The most reliable solution for non-interactive environments is to bypass the Keychain entirely:
For HTTPS authentication with Personal Access Token:
# Set credentials via environment variable
export GIT_ASKPASS=/bin/echo
export GIT_USERNAME="your-username"
export GIT_PASSWORD="your-personal-access-token"
# Or embed credentials in the URL (less secure but works)
git clone https://username:[email protected]/owner/repo.git
# Or use the credential helper store (stores in plain text file)
git config --global credential.helper storeSet credentials for the session:
# Configure Git to use specific credentials for this session
git config credential.helper '!f() { echo "username=$GIT_USERNAME"; echo "password=$GIT_PASSWORD"; }; f'For CI/CD environments, set secrets in your CI config:
GitHub Actions:
- name: Clone repository
run: |
git clone https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/owner/repo.gitJenkins:
withCredentials([usernamePassword(credentialsId: 'github-creds', usernameVariable: 'GIT_USER', passwordVariable: 'GIT_TOKEN')]) {
sh 'git clone https://$GIT_USER:[email protected]/owner/repo.git'
}SSH keys don't require Keychain access and work reliably in non-interactive environments:
Generate an SSH key (if needed):
ssh-keygen -t ed25519 -C "[email protected]" -f ~/.ssh/id_ed25519 -N ""
# -N "" creates the key without a passphrase (required for automation)Add the public key to your Git provider:
cat ~/.ssh/id_ed25519.pub
# Copy this output to GitHub/GitLab SSH keys settingsChange remote URL from HTTPS to SSH:
# Check current remote
git remote -v
# Change from HTTPS to SSH
git remote set-url origin [email protected]:owner/repo.git
# Verify the change
git remote -vFor CI/CD, add SSH key to the agent:
# Start SSH agent
eval "$(ssh-agent -s)"
# Add key (no passphrase required for automation)
ssh-add ~/.ssh/id_ed25519
# Or add from environment variable
echo "$SSH_PRIVATE_KEY" | ssh-add -If you don't want Git to use the macOS Keychain at all:
Remove the Keychain credential helper:
# Check current credential helper
git config --global credential.helper
# If it shows 'osxkeychain', remove it
git config --global --unset credential.helper
# Or set it to 'store' or 'cache' instead
git config --global credential.helper store # Stores in ~/.git-credentials (plain text)
git config --global credential.helper cache # Caches in memory for 15 minutesFor a specific repository only:
# Override for this repo only
git config credential.helper storeDisable credential storage entirely:
# Don't store credentials at all (will prompt every time)
git config --global credential.helper ""If you want to keep using Keychain but avoid the prompt, you can modify the Keychain item's Access Control settings:
Using Keychain Access app:
1. Open Keychain Access (Applications > Utilities)
2. Search for "github" or your Git host
3. Double-click the credential item
4. Go to Access Control tab
5. Either:
- Select "Allow all applications to access this item"
- Or add git-credential-osxkeychain to the allowed applications list
6. Click "Save Changes" (you'll need to enter your password)
Using command line:
# Find the credential item
security find-generic-password -s "github.com" -l "github.com"
# Delete and re-add with different permissions
security delete-generic-password -s "github.com"
# Add without ACL restrictions (accessible by all apps)
security add-generic-password -a "username" -s "github.com" -w "your-token" -AWarning: The -A flag makes the credential accessible to all applications, which reduces security.
If running Git from a launchd service, ensure it has the right context:
Example launchd plist with proper environment:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.example.gitbackup</string>
<key>ProgramArguments</key>
<array>
<string>/bin/bash</string>
<string>-c</string>
<string>/usr/local/bin/git -C /path/to/repo pull</string>
</array>
<key>StartInterval</key>
<integer>3600</integer>
<key>SessionCreate</key>
<true/>
<key>AcquireUserEnvironment</key>
<true/>
</dict>
</plist>Key settings:
- SessionCreate: Creates a new security session
- AcquireUserEnvironment: Inherits user environment variables
Alternative: Use SSH in launchd jobs:
<key>EnvironmentVariables</key>
<dict>
<key>SSH_AUTH_SOCK</key>
<string>/tmp/ssh-agent.sock</string>
</dict>For macOS CI/CD runners, configure authentication properly:
GitHub Actions on macOS:
jobs:
build:
runs-on: macos-latest
steps:
- name: Configure Git credentials
run: |
# Use HTTPS with token
git config --global credential.helper store
echo "https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com" > ~/.git-credentials
- name: Checkout
uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
# Or use SSH
- name: Setup SSH
uses: webfactory/[email protected]
with:
ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}Jenkins on macOS:
pipeline {
agent { label 'macos' }
environment {
GIT_CREDENTIALS = credentials('github-token')
}
stages {
stage('Checkout') {
steps {
sh '''
git config --global credential.helper store
echo "https://[email protected]" > ~/.git-credentials
git clone https://github.com/owner/repo.git
'''
}
}
}
}Unlock Keychain in CI (if you must use it):
- name: Unlock Keychain
run: |
security unlock-keychain -p "${{ secrets.KEYCHAIN_PASSWORD }}" ~/Library/Keychains/login.keychain-db
security set-keychain-settings -lut 7200 ~/Library/Keychains/login.keychain-db### Understanding macOS Keychain Security
The macOS Keychain uses Access Control Lists (ACLs) to determine which applications can access stored credentials:
1. "Always Allow": Application can access without prompting
2. "Confirm before allowing": Requires user to click "Allow" in a dialog
3. "Deny": Application cannot access the item
When Git runs in a non-interactive context, option 2 fails because there's no user to click the dialog, resulting in "User interaction is not allowed."
### Keychain Lock States
The login Keychain can be in different states:
- Unlocked: Credentials are accessible
- Locked: Requires password to unlock
- Auto-lock: Locks after a period of inactivity or sleep
# Check lock status
security show-keychain-info ~/Library/Keychains/login.keychain-db
# Set auto-lock timeout (in seconds, 0 = never)
security set-keychain-settings -lut 28800 ~/Library/Keychains/login.keychain-db### Creating a Dedicated CI Keychain
For CI environments, you can create a separate Keychain:
# Create a new keychain
security create-keychain -p "$KEYCHAIN_PASSWORD" ci.keychain
# Set it as the default
security default-keychain -s ci.keychain
# Unlock it
security unlock-keychain -p "$KEYCHAIN_PASSWORD" ci.keychain
# Set timeout
security set-keychain-settings -lut 7200 ci.keychain
# Add to search list
security list-keychains -d user -s ci.keychain login.keychain
# Import credentials or certificates
security import certificate.p12 -k ci.keychain -P "$CERT_PASSWORD" -T /usr/bin/codesign -T /usr/bin/git-credential-osxkeychain### Git Credential Helper Chain
Git can use multiple credential helpers in sequence:
# Configure fallback chain
git config --global credential.helper ''
git config --global --add credential.helper 'cache --timeout=3600'
git config --global --add credential.helper storeThis tries cache first, then falls back to store.
### Security Considerations
When bypassing the Keychain for automation:
1. Environment variables: Visible in process lists (ps aux)
2. Git credential store: Plain text file (~/.git-credentials)
3. URL-embedded tokens: May be logged in shell history or error messages
Best practices:
- Use short-lived tokens when possible
- Rotate credentials regularly
- Use CI/CD secrets management
- Prefer SSH keys over HTTPS tokens for automation
- Never commit credentials to repositories
### Debugging Keychain Issues
# List all keychains
security list-keychains
# Find Git-related items in Keychain
security find-generic-password -s "github.com" 2>&1
# Check which credential helper Git is using
git config --show-origin --get credential.helper
# Test credential helper directly
echo "protocol=https
host=github.com" | git credential fill
# Verbose Git output
GIT_TRACE=1 GIT_CURL_VERBOSE=1 git fetch### macOS Versions and Keychain Behavior
Different macOS versions may have slightly different Keychain behaviors:
- macOS Catalina (10.15)+: Stricter security with increased prompting
- macOS Big Sur (11)+: Security framework changes affecting automation
- macOS Ventura (13)+: New security prompts for network access
If you recently upgraded macOS and started seeing this error, you may need to re-authorize applications in Keychain Access.
kex_exchange_identification: Connection closed by remote host
Connection closed by remote host when connecting to Git server
fatal: unable to access: Proxy auto-configuration failed
How to fix 'Proxy auto-configuration failed' in Git
fatal: unable to access: Authentication failed (proxy requires basic auth)
How to fix 'Authentication failed (proxy requires basic auth)' in Git
fatal: unable to access: no_proxy configuration not working
How to fix 'no_proxy configuration not working' in Git
fatal: unable to read tree object in treeless clone
How to fix 'unable to read tree object in treeless clone' in Git