Infisical Secrets Management#
Overview#
Infisical provides centralized secrets management for the observatory, replacing scattered .env files and manual credential sharing. Access is controlled via GitHub organization membership, with secrets pulled dynamically at deployment time and available to developers through Web UI or CLI.
Key Benefits:
Single source of truth for all credentials
GitHub OAuth single sign-on
Role-based access via GitHub teams
Audit trail of all access
No secrets in git repositories
Centralized credential rotation
Architecture#
GitHub Organization (Authentication)
↓
Infisical (Central Storage)
↓
┌───────┴───────┬──────────┬──────────┐
│ │ │ │
Web UI CLI Ansible Jenkins/GH Actions
(humans) (humans) (deploy) (CI/CD)
Components:
GitHub OAuth: Authentication via existing GitHub accounts
Infisical Server: Hosted at
infisical.data.ccat.uni-koeln.deProjects: Logical groupings of secrets (Science, Infrastructure, Development)
Environments: Separate secrets for Production, Staging, Development
Service Tokens: Machine credentials for automated systems
Projects and Access Control#
Access is determined by GitHub team membership TO BE UPDATED AND DISCUSSED EXAMPLES:
GitHub Team |
Infisical Project |
Access Level |
|---|---|---|
|
Data Center |
Admin (Full Control) |
|
Developer |
Admin (Full Control) |
|
CHAI |
Member (Read/Write) |
|
PrimeCam |
Member (Read/Write) |
Each project contains secrets scoped to different environments (Production, Staging, Development).
Accessing Secrets#
Web UI Access#
For quick lookups and browsing:
Navigate to
https://infisical.data.ccat.uni-koeln.deClick “Login with GitHub”
Authorize the application (first time only)
Browse to your project (e.g., “Science APIs”)
Select environment (Production, Staging, Development)
Click on a secret to reveal its value
Copy the value for use
Use cases:
Looking up API tokens
Finding SSH credentials during incidents
Checking database connection strings
Verifying configuration values
CLI Installation#
For developers who prefer command-line workflows:
Debian/Ubuntu:
curl -1sLf \
'https://artifacts-cli.infisical.com/setup.deb.sh' \
| sudo -E bash
sudo apt-get update && sudo apt-get install -y infisical
macOS:
brew install infisical/get-cli/infisical
RedHat/CentOS:
curl -1sLf \
'https://dl.cloudsmith.io/public/infisical/infisical-cli/setup.rpm.sh' \
| sudo -E bash
sudo yum install -y infisical
One-time authentication:
infisical login
This opens a browser for GitHub OAuth and saves a token locally at ~/.config/infisical/config.json.
CLI Usage Examples#
Get a specific secret:
infisical secrets get API_TOKEN \
--projectId=64abc123def456 \
--env=development
Export all secrets to .env file:
infisical export \
--projectId=64abc123def456 \
--env=development > .env
Run a command with secrets injected:
infisical run \
--projectId=64abc123def456 \
--env=development \
-- python analysis_script.py
The command runs with all project secrets available as environment variables.
List all secrets (without values):
infisical secrets list \
--projectId=64abc123def456 \
--env=development
Finding Project IDs#
Project IDs are available in the Web UI:
Navigate to your project
Go to Settings → General
Copy the Project ID
Alternatively, list all accessible projects:
infisical projects list
Managing Secrets#
Adding Secrets#
Via Web UI:
Navigate to project and environment
Click “Add Secret”
Enter key (e.g.,
DATABASE_PASSWORD)Enter value
Click “Save”
Via CLI:
infisical secrets set DATABASE_PASSWORD "newpassword123" \
--projectId=64abc123def456 \
--env=production
Updating Secrets#
Via Web UI:
Navigate to the secret
Click “Edit”
Update value
Click “Save”
Changes propagate immediately to all systems pulling from Infisical.
Via CLI:
infisical secrets set API_TOKEN "new-token-value" \
--projectId=64abc123def456 \
--env=production
Rotating Credentials#
When rotating credentials (e.g., database passwords, API tokens):
Update the secret in Infisical (Web UI or CLI)
Update the credential in the target system (database, API service)
Trigger redeployment or restart services to pick up new value
Services using infisical run will pick up changes on next restart. For long-running services, a redeployment is required.
Deleting Secrets#
Via Web UI:
Navigate to the secret
Click “Delete”
Confirm deletion
Via CLI:
infisical secrets delete OLD_API_KEY \
--projectId=64abc123def456 \
--env=development
SSH Access Management#
Store SSH credentials as secrets for centralized management and audit trails.
Storing SSH Credentials#
Username/Password access:
Create secrets in the Infrastructure project:
SSH_SERVER01_USER:adminSSH_SERVER01_PASSWORD:securepasswordSSH_SERVER01_HOST:server01.observatory.local
SSH Private Keys:
For private keys (multi-line values):
Web UI: Paste the entire private key including headers (
-----BEGIN OPENSSH PRIVATE KEY-----)CLI: Use quotes and preserve newlines:
infisical secrets set SSH_DEPLOY_KEY "$(cat ~/.ssh/deploy_key)" \
--projectId=64abc123def456 \
--env=production
Retrieving SSH Credentials#
Interactive lookup (Web UI):
Navigate to Infrastructure project → Production environment
Find
SSH_SERVER01_PASSWORDClick to reveal and copy
Use in terminal:
ssh admin@server01.observatory.local
CLI retrieval:
# Get password
PASSWORD=$(infisical secrets get SSH_SERVER01_PASSWORD \
--projectId=64abc123def456 \
--env=production \
--plain)
# Use with sshpass (if needed)
sshpass -p "$PASSWORD" ssh admin@server01.observatory.local
SSH key usage:
# Export key to temporary file
infisical secrets get SSH_DEPLOY_KEY \
--projectId=64abc123def456 \
--env=production \
--plain > /tmp/deploy_key
chmod 600 /tmp/deploy_key
ssh -i /tmp/deploy_key user@server.local
rm /tmp/deploy_key
Best practices:
Use SSH keys instead of passwords where possible
Store connection details (host, user, port) alongside credentials
Document which key/credential is for which server
Rotate SSH passwords regularly
Use service accounts for automated access
CI/CD Integration#
GitHub Actions#
Self-Hosted Runners:
Our GitHub Actions runners operate on observatory infrastructure with access to Infisical.
Accessing secrets in workflows:
name: Build and Deploy
on:
push:
branches: [main]
jobs:
build:
runs-on: [self-hosted, linux]
steps:
- uses: actions/checkout@v4
- name: Pull secrets from Infisical
run: |
infisical export \
--projectId=${{ secrets.INFISICAL_PROJECT_ID }} \
--env=production \
--token=${{ secrets.INFISICAL_TOKEN }} > .env
- name: Build application
run: |
source .env
docker build -t myapp:latest .
- name: Run with secrets
run: |
infisical run \
--projectId=${{ secrets.INFISICAL_PROJECT_ID }} \
--env=production \
--token=${{ secrets.INFISICAL_TOKEN }} \
-- docker-compose up -d
Required GitHub Secrets:
Configure these in your repository settings (Settings → Secrets and variables → Actions):
INFISICAL_TOKEN: Service token for the projectINFISICAL_PROJECT_ID: Project ID from Infisical
Creating service tokens:
In Infisical Web UI, navigate to project
Go to Settings → Service Tokens
Click “Create Service Token”
Set name (e.g.,
github-actions-production)Set environment (Production, Staging, or Development)
Set permissions (Read or Read/Write)
Copy the generated token (starts with
st.)Add to GitHub repository secrets
Jenkins Integration#
Jenkins jobs SSH to target servers where Infisical CLI is installed.
Deployment flow:
GitHub Actions → Build containers → Trigger Jenkins
↓
Jenkins → SSH to server → Execute deploy script
↓
Server → infisical run -- docker-compose up -d
Jenkins pipeline example:
pipeline {
agent any
stages {
stage('Deploy to Production') {
steps {
sshagent(['production-ssh-key']) {
sh '''
ssh deploy@prod-server-01 "/opt/deploy/deploy.sh"
'''
}
}
}
}
}
Server deployment script (/opt/deploy/deploy.sh):
#!/bin/bash
set -e
# Load service token
export INFISICAL_TOKEN=$(cat /etc/infisical/token)
cd /opt/myapp
# Pull latest containers
docker-compose pull
# Deploy with secrets from Infisical
infisical run \
--projectId=64abc123def456 \
--env=production \
-- docker-compose up -d
echo "Deployment complete at $(date)"
Server Setup with Ansible#
Servers are provisioned with Infisical CLI and service tokens via Ansible.
Ansible role structure:
roles/infisical/
├── tasks/
│ └── main.yml
└── templates/
├── infisical-token.j2
└── deploy.sh.j2
Service token storage:
Service tokens are stored in Ansible Vault at group_vars/production.yml:
---
infisical_token: "st.prod.abc123..."
infisical_project_id: "64abc123def456"
Deploy script template (templates/deploy.sh.j2):
#!/bin/bash
set -e
export INFISICAL_TOKEN=$(cat /etc/infisical/token)
cd /opt/{{ app_name }}
docker-compose pull
infisical run \
--projectId={{ infisical_project_id }} \
--env={{ environment }} \
-- docker-compose up -d
echo "Deployment complete"
Ansible playbook execution:
# Setup production servers
ansible-playbook -i inventory/production \
playbooks/setup-infisical.yml \
--ask-vault-pass
Local Development Workflow#
Typical developer workflow for local testing:
Option 1: Generate .env file
cd ~/projects/myapp
# Pull development secrets
infisical export \
--projectId=64abc123def456 \
--env=development > .env
# Run application normally
docker-compose up
Option 2: Run with injected secrets
cd ~/projects/myapp
# Run directly with secrets
infisical run \
--projectId=64abc123def456 \
--env=development \
-- docker-compose up
Option 3: Manual lookup
For one-off scripts or notebooks:
# Get specific secret
API_KEY=$(infisical secrets get OBSERVATION_API_TOKEN \
--projectId=64abc123def456 \
--env=development \
--plain)
# Use in script
python analyze_data.py --api-key="$API_KEY"
Security Best Practices#
Network Access#
Infisical is accessible only from:
University network (direct)
University VPN
Whitelisted collaborator institutions
Observatory on-premises network
Access is enforced via nginx-proxy IP whitelisting.
Audit Logging#
All secret access is logged in Infisical:
Who accessed which secret
When it was accessed
From which IP address
What action was taken (read, write, delete)
Admins can review logs in Settings → Audit Logs.
Secret Rotation#
Rotate credentials regularly:
Monthly: API tokens for external services
Quarterly: Database passwords
Annually: SSH keys
Immediately: When team member leaves or credential compromised
Update in Infisical first, then update in target system, then redeploy.
Least Privilege#
Use environment-specific secrets (don’t use production secrets in development)
Grant minimum required access (Viewer vs Member vs Admin)
Use service tokens with read-only access where possible
Scope service tokens to specific environments
Never Commit Secrets#
Secrets should never appear in:
Git repositories
Docker images
Log files
Slack messages
Email
Use Infisical for all credential storage and retrieval.
Troubleshooting#
CLI Authentication Issues#
Problem: infisical login fails
Solution:
Ensure you can access
https://infisical.data.ccat.uni-koeln.dein browserCheck VPN connection
Verify GitHub OAuth app is authorized in GitHub settings
Try re-logging:
rm ~/.config/infisical/config.json && infisical login
Service Token Invalid#
Problem: CI/CD fails with “Invalid token”
Solution:
Verify token in Infisical UI (Settings → Service Tokens)
Check token hasn’t expired
Regenerate token and update in GitHub Secrets or Ansible Vault
Ensure token has correct environment permissions
Secrets Not Updating#
Problem: Changed secret in Infisical but application still uses old value
Solution:
For
infisical runcommands: Restart the serviceFor exported
.envfiles: Re-runinfisical exportFor containerized apps: Redeploy (
docker-compose up -d)Check that service token has read access to the environment
Permission Denied#
Problem: “You don’t have permission to access this project”
Solution:
Verify your GitHub team membership at
https://github.com/orgs/YOUR_ORG/teamsAsk admin to add your team to the Infisical project
Log out and back in to refresh permissions
Check you’re accessing the correct environment (Production vs Development)
Support and Documentation#
Infisical Web UI: https://infisical.data.ccat.uni-koeln.de
Official Documentation: https://infisical.com/docs
CLI Reference: https://infisical.com/docs/cli/overview
Internal Issues: Contact
@observatory/infrastructureteamEmergency Access: Use university VPN + Web UI for credential lookup
Appendix: Common Commands#
# Authentication
infisical login
infisical logout
# List projects
infisical projects list
# List secrets in project
infisical secrets list --projectId=<id> --env=<env>
# Get specific secret
infisical secrets get <KEY> --projectId=<id> --env=<env>
# Get secret value only (for scripting)
infisical secrets get <KEY> --projectId=<id> --env=<env> --plain
# Set secret
infisical secrets set <KEY> "<value>" --projectId=<id> --env=<env>
# Delete secret
infisical secrets delete <KEY> --projectId=<id> --env=<env>
# Export to .env
infisical export --projectId=<id> --env=<env> > .env
# Run command with secrets
infisical run --projectId=<id> --env=<env> -- <command>
# Using service token (CI/CD)
infisical export --token=<service-token> --env=<env> > .env
infisical run --token=<service-token> --env=<env> -- <command>