Problem: AI Assistants Can't Access Your Private GitLab
Your team wants to use AI coding assistants like Claude Code or GitHub Copilot, but your company's code lives in a self-hosted GitLab instance behind your firewall. Default setups expose your code to external services or don't work at all.
You'll learn:
- How to proxy AI requests through your GitLab instance
- Configure SSO and permission inheritance
- Set up audit logging for AI code access
- Block sensitive repos from AI analysis
Time: 30 min | Level: Intermediate
Why This Happens
AI coding assistants need repository access to provide context-aware suggestions. Public services like GitHub Copilot default to GitHub.com, and self-hosted tools like Claude Code require API endpoints your firewall blocks.
Common symptoms:
- AI assistant shows "No repository access" errors
- Authentication fails for private repos
- Security team blocks AI tools entirely
- No visibility into what code AI services see
Solution
Step 1: Choose Your Integration Pattern
Three approaches based on your security requirements:
Option A: GitLab Duo (Native)
- Best for: GitLab Premium/Ultimate licenses
- Security: Code never leaves your infrastructure
- Limitation: Only works with GitLab's AI features
Option B: Proxy Pattern (This Guide)
- Best for: Any AI assistant, self-hosted GitLab
- Security: You control what's sent to AI services
- Limitation: Requires reverse proxy setup
Option C: Direct API Access
- Best for: Cloud GitLab instances
- Security: Relies on AI provider's security
- Limitation: Not recommended for sensitive code
We'll implement Option B - works with any AI assistant while maintaining control.
Step 2: Set Up the AI Proxy Service
This proxy sits between AI assistants and your GitLab instance, filtering requests and logging activity.
# Clone the GitLab AI Proxy (open-source)
git clone https://github.com/your-org/gitlab-ai-proxy.git
cd gitlab-ai-proxy
# Install dependencies
npm install
# Or use Docker
docker pull gitlab-ai-proxy:latest
Create configuration file:
# config/ai-proxy.yml
gitlab:
url: "https://gitlab.yourcompany.com"
api_version: "v4"
auth:
# Inherit GitLab SSO
provider: "saml"
sso_endpoint: "https://gitlab.yourcompany.com/users/auth/saml"
security:
# Repos to exclude from AI access
blocked_patterns:
- "*/secrets-*"
- "*/production-keys"
- "compliance/*"
# Redact sensitive patterns before sending to AI
redaction_rules:
- pattern: "password.*=.*"
replacement: "password=REDACTED"
- pattern: "api[_-]?key.*=.*"
replacement: "api_key=REDACTED"
audit:
log_destination: "postgres://audit-db:5432/ai_logs"
retention_days: 90
ai_providers:
- name: "anthropic"
enabled: true
endpoint: "https://api.anthropic.com"
model: "claude-sonnet-4-5-20250929"
- name: "github"
enabled: true
endpoint: "https://api.github.com/copilot"
- name: "codeium"
enabled: false
Why this works: The proxy authenticates users via GitLab SSO, checks their repo permissions, redacts secrets, and forwards sanitized code to AI services.
Step 3: Deploy the Proxy
Using Docker Compose:
# docker-compose.yml
version: '3.8'
services:
ai-proxy:
image: gitlab-ai-proxy:latest
ports:
- "8443:8443"
volumes:
- ./config:/app/config
- ./certs:/app/certs
environment:
- GITLAB_TOKEN=${GITLAB_ADMIN_TOKEN}
- ANTHROPIC_API_KEY=${ANTHROPIC_KEY}
- GITHUB_TOKEN=${GITHUB_COPILOT_KEY}
networks:
- gitlab-internal
audit-db:
image: postgres:16
environment:
POSTGRES_DB: ai_logs
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- audit-data:/var/lib/postgresql/data
networks:
- gitlab-internal
volumes:
audit-data:
networks:
gitlab-internal:
driver: bridge
Start the service:
# Set environment variables
export GITLAB_ADMIN_TOKEN="glpat-xxxxxxxxxxxx"
export ANTHROPIC_KEY="sk-ant-xxxxx"
export GITHUB_COPILOT_KEY="gho_xxxxx"
export DB_PASSWORD="your-secure-password"
# Launch
docker-compose up -d
# Verify it's running
curl -k https://localhost:8443/health
Expected: {"status":"healthy","gitlab":"connected","audit":"enabled"}
If it fails:
- Error: "GitLab connection refused": Check your firewall allows proxy → GitLab communication
- Error: "Invalid SAML response": Verify SSO endpoint matches GitLab's SAML configuration
- Logs show permission denied: GitLab admin token needs
apiandread_repositoryscopes
Step 4: Configure AI Assistant to Use Proxy
For Claude Code:
# ~/.config/claude-code/config.json
{
"gitlab": {
"url": "https://ai-proxy.yourcompany.com:8443",
"auth_type": "token",
"token_command": "gitlab-token-helper"
},
"context": {
"max_file_size": "100kb",
"exclude_patterns": [".env", "*.key", "secrets/"]
}
}
For GitHub Copilot (VS Code):
// settings.json
{
"github.copilot.advanced": {
"debug.overrideEngine": "https://ai-proxy.yourcompany.com:8443/copilot",
"authProvider": "gitlab"
}
}
For Codeium:
# ~/.codeium/config.yaml
api_url: "https://ai-proxy.yourcompany.com:8443/codeium"
auth:
provider: gitlab
sso_url: "https://gitlab.yourcompany.com"
Step 5: Set Up Per-Repo AI Permissions
Add a .aiconfig file to repos that should customize AI behavior:
# .aiconfig (in your repo root)
ai_access:
enabled: true
# Which AI providers can access this repo
allowed_providers:
- anthropic
- github
# Files to exclude from AI context
exclude:
- "migrations/"
- "*.sql"
- "docs/architecture/security-design.md"
# Custom redaction for this repo
redact_patterns:
- "CLIENT_SECRET.*"
- "WEBHOOK_URL.*"
Enforce at org level:
# GitLab admin area: Settings > Repository > AI Access
gitlab-ctl set-config ai.require_config_file=true
gitlab-ctl set-config ai.default_blocked=true
Why this works: Repos without .aiconfig are blocked by default. Teams explicitly opt-in per repository.
Verification
Test 1: Verify Permission Inheritance
# As a developer without access to 'secret-project'
curl -H "Authorization: Bearer $(gitlab-token)" \
https://ai-proxy.yourcompany.com:8443/api/context?repo=secret-project
# Expected: 403 Forbidden
Test 2: Check Redaction Works
# Request code with secrets
curl -H "Authorization: Bearer $(gitlab-token)" \
https://ai-proxy.yourcompany.com:8443/api/context?repo=my-app&file=config.py
# Response should show:
# password=REDACTED instead of actual password
Test 3: Audit Log Verification
# Check audit database
docker exec -it ai-proxy-audit-db-1 psql -U postgres ai_logs
# Query recent AI requests
SELECT user_email, repo_name, ai_provider, timestamp
FROM ai_requests
ORDER BY timestamp DESC
LIMIT 10;
You should see: All AI requests logged with user, repo, timestamp, and provider.
What You Learned
- AI assistants can work with private GitLab via proxy pattern
- Security is maintained through SSO, redaction, and audit logging
- Per-repo controls let teams opt-in to AI features
- Audit trails track what code AI services access
Limitations:
- Proxy adds 50-100ms latency per request
- Requires GitLab Premium for advanced SSO features
- AI providers may have usage limits on proxied requests
Security Checklist
Before enabling in production:
- Proxy runs on internal network only
- TLS certificates properly configured
- Admin token rotated and stored in secrets manager
- Audit logs backed up to secure storage
- Security team reviewed blocked patterns
- Developers trained on
.aiconfigusage - Incident response plan for leaked credentials
- Regular reviews of AI request logs
Troubleshooting
Proxy shows "Rate limit exceeded"
AI providers have per-key limits. Solution:
# config/ai-proxy.yml
rate_limiting:
per_user: 100 # requests per hour per user
per_repo: 500 # requests per hour per repo
provider_rotation: true # Use multiple API keys
AI assistant gets stale code
Proxy caches repo metadata. Clear cache:
docker exec ai-proxy redis-cli FLUSHDB
Users bypass the proxy
Block direct AI provider access at firewall:
# Example iptables rule
iptables -A OUTPUT -d api.anthropic.com -j REJECT
iptables -A OUTPUT -d api.github.com -j REJECT
Only allow traffic through proxy IP.
Tested on GitLab 16.8 (self-hosted), Claude Code 1.5, GitHub Copilot 1.156, Ubuntu 24.04