Purpose: For operators, shows how to configure SSH key or token-based authentication for FluxCD bootstrap, covering GitHub, GitLab, and Gitea providers.
FluxCD bootstrap requires Git repository access. openCenter supports two authentication methods:
-
SSH Key Authentication: Recommended for production. Uses SSH key pairs for secure, passwordless access.
-
Token Authentication: Useful for HTTPS-only environments. Uses personal access tokens (PAT) for authentication.
Prerequisites
-
openCenter CLI installed
-
Cluster configuration created (
opencenter cluster init) -
Git repository created (GitHub, GitLab, or Gitea)
-
Admin access to create tokens or deploy keys
Choose Your Authentication Method
| Method | Use Case | Security | Setup Complexity | | --- | --- | --- | --- | | SSH Key | Production, CI/CD | High (key-based) | Medium | | Token | HTTPS-only, quick setup | Medium (token-based) | Low |
Recommendation: Use SSH keys for production clusters. Use tokens for local development or environments where SSH is blocked.
SSH Key Authentication
Step 1: Generate SSH Key Pair
openCenter generates SSH keys during cluster initialization:
opencenter cluster init my-cluster --org my-org
Keys are created at:
-
Private key:
~/.config/opencenter/clusters/my-org/secrets/ssh/my-cluster-key -
Public key:
~/.config/opencenter/clusters/my-org/secrets/ssh/my-cluster-key.pub
To generate keys manually:
ssh-keygen -t ed25519 -C "flux-my-cluster" -f ~/.config/opencenter/clusters/my-org/secrets/ssh/my-cluster-key -N ""
Step 2: Add Deploy Key to Repository
GitHub
-
Navigate to your repository on GitHub
-
Go to Settings → Deploy keys
-
Click Add deploy key
-
Enter a title (e.g.,
flux-my-cluster) -
Paste the public key content:
```bash cat ~/.config/opencenter/clusters/my-org/secrets/ssh/my-cluster-key.pub ``` . Check *Allow write access* (required for Flux to push status updates) . Click *Add key*
Step 3: Configure openCenter
Update your cluster configuration to use SSH:
opencenter:
gitops:
repository:
url: "ssh://git@github.com/my-org/my-cluster-gitops.git"
branch: "main"
auth:
ssh:
private_key: "~/.config/opencenter/clusters/my-org/secrets/ssh/my-cluster-key"
public_key: "~/.config/opencenter/clusters/my-org/secrets/ssh/my-cluster-key.pub"
To open the guided configuration workflow:
opencenter cluster configure my-org/my-cluster --guided
Token Authentication
Step 1: Create Personal Access Token
GitHub
-
Go to GitHub → Settings → Developer settings → Personal access tokens → Tokens (classic)
-
Click Generate new token → Generate new token (classic)
-
Enter a note (e.g.,
flux-my-cluster) -
Set expiration (recommend 90 days for rotation)
-
Select scopes:
-
repo(Full control of private repositories)
-
-
Click Generate token
-
Copy the token immediately (it won’t be shown again)
Fine-grained tokens (recommended for GitHub):
-
Go to Settings → Developer settings → Personal access tokens → Fine-grained tokens
-
Click Generate new token
-
Enter a token name (e.g.,
flux-my-cluster) -
Set expiration
-
Select Repository access → Only select repositories → choose your GitOps repo
-
Under Permissions → Repository permissions:
-
Contents: Read and write
-
Metadata: Read-only (automatically selected)
-
-
Click Generate token
-
Copy the token immediately
GitLab
-
Go to GitLab → User Settings → Access Tokens
-
Click Add new token
-
Enter a name (e.g.,
flux-my-cluster) -
Set expiration date
-
Select scopes:
-
api(for full API access), or -
read_repository+write_repository(minimal)
-
-
Click Create personal access token
-
Copy the token immediately
Project access tokens (recommended for GitLab):
-
Navigate to your project
-
Go to Settings → Access Tokens
-
Click Add new token
-
Enter a name and expiration
-
Select role: Maintainer
-
Select scopes:
read_repository,write_repository -
Click Create project access token
-
Copy the token
Step 2: Store Token Securely
Create a token file (never commit this to Git):
# Create token file
echo "ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" > ~/.config/opencenter/clusters/my-org/secrets/git-token.txt
# Secure permissions
chmod 600 ~/.config/opencenter/clusters/my-org/secrets/git-token.txt
Step 3: Configure openCenter
Update your cluster configuration to use token authentication:
opencenter:
gitops:
repository:
url: "https://github.com/my-org/my-cluster-gitops.git"
branch: "main"
auth:
token:
provider: "github" # or "gitlab", "gitea"
token: "ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
owner: "my-org" # optional: overrides owner extracted from URL
Set either token or token_file: "~/.config/opencenter/clusters/my-org/secrets/git-token.txt". The default cluster init template uses token: "CHANGEME" so generated configs are actionable without guessing the field name; replace it before deployment. The token owner field is optional. If not specified, openCenter extracts the owner from the repository URL. Use owner when:
-
The URL owner differs from the token owner (e.g., organization vs personal account)
-
Using a personal token with
--personalflag for GitHub
To open the guided configuration workflow:
opencenter cluster configure my-org/my-cluster --guided
Verification
After bootstrap, verify authentication is working:
# Check GitRepository status
kubectl get gitrepositories -n flux-system
# Expected output shows Ready status
NAME URL READY STATUS
flux-system ssh://git@github.com/my-org/my-cluster-gitops True Fetched revision: main@sha1:abc123
If authentication fails:
# Check detailed status
kubectl describe gitrepository flux-system -n flux-system
# Check Flux logs
kubectl logs -n flux-system deployment/source-controller
Rotate Credentials
Troubleshooting
SSH: Permission Denied
Problem: Permission denied (publickey) during bootstrap.
Causes:
-
Deploy key not added to repository
-
Wrong key file path in configuration
-
Key doesn’t have write access
Solution:
# Verify key exists
ls -la ~/.config/opencenter/clusters/my-org/secrets/ssh/
# Test SSH connection (GitHub example)
ssh -T -i ~/.config/opencenter/clusters/my-org/secrets/ssh/my-cluster-key git@github.com
# Verify deploy key has write access in repository settings
Token: Authentication Failed
Problem: authentication required or 401 Unauthorized during bootstrap.
Causes:
-
Token expired
-
Insufficient token scopes
-
Wrong token provider configured
Solution:
# Verify token file exists and has content
cat ~/.config/opencenter/clusters/my-org/secrets/git-token.txt
# Test token (GitHub example)
curl -H "Authorization: token $(cat ~/.config/opencenter/clusters/my-org/secrets/git-token.txt)" \
https://api.github.com/user
# Regenerate token with correct scopes if needed
GitRepository Stuck in "Fetching"
Problem: GitRepository shows Fetching status indefinitely.
Causes:
-
Network connectivity issues
-
Firewall blocking Git protocol
-
Invalid repository URL
Solution:
# Check source-controller logs
kubectl logs -n flux-system deployment/source-controller | tail -50
# Verify URL is accessible from cluster
kubectl run -it --rm debug --image=alpine --restart=Never -- \
sh -c "apk add git && git ls-remote https://github.com/my-org/my-cluster-gitops.git"
Security Best Practices
SSH Keys
-
Use Ed25519 keys (more secure than RSA)
-
Store private keys with
600permissions -
Use deploy keys (repository-scoped) instead of user SSH keys
-
Rotate keys every 180 days
Next Steps
-
manage-secrets.md[Manage Secrets] - Encrypt secrets with SOPS
-
troubleshoot-deployment.md[Troubleshoot Deployment] - Fix bootstrap issues
-
../concepts/gitops-workflow.md[GitOps Workflow] - Understand reconciliation
Evidence
This how-to guide is based on:
-
GitOps configuration:
internal/config/types_gitops.go:17-23(GitToken, GitTokenProvider, GitOwner fields) -
Bootstrap implementation:
internal/localdev/flux/service.go:51-160(provider-specific bootstrap commands) -
URL parsing:
internal/localdev/flux/service.go:162-230(parseGitHubURL, parseGitLabURL, parseGitURL) -
SSH key generation:
internal/sops/manager.go -
Security model:
docs/concepts/security-model.md:104-108 -
FluxCD documentation: https://fluxcd.io/docs/installation/bootstrap/