Vault Secrets Backend Plugin
The Vault Secrets Backend provides HashiCorp Vault integration with support for both GCP IAM authentication (production) and JWT-based authentication (development).
Overview
| Property | Value |
|---|---|
| Package | @internal/backstage-plugin-vault-secrets-backend |
| Type | Backend |
| Plugin ID | vault-secrets |
| Auth | GCP IAM + JWT |
Architecture
API Endpoints
Health & Debug
| Method | Endpoint | Description |
|---|---|---|
| GET | /health | Vault connection status |
| GET | /debug/config | Configuration info |
| GET | /debug/jwt | JWT claims inspection |
| GET | /user-info | Current user information |
Secret Operations
| Method | Endpoint | Description |
|---|---|---|
| GET | /secrets | List secrets |
| GET | /secrets/:path(*) | Read secret |
| POST | /secrets/:path(*) | Write secret |
| DELETE | /secrets/:path(*) | Delete secret |
Authentication
Dual Auth Strategy
GCP IAM Authentication (Production)
When running on Cloud Run, the backend authenticates to Vault using GCP IAM:
// Automatic when GOOGLE_CLOUD_PROJECT is set
const auth = new GoogleAuth();
const client = await auth.getIdTokenClient(vaultIapAudience);
JWT Authentication (Development)
For local development, JWT tokens from Backstage are used:
// JWT claims extracted for user/group info
interface JWTClaims {
sub: string; // User reference
ent: string[]; // Entity claims (groups)
"github.teams": string[]; // GitHub team memberships
}
Access Control
User Keystore Access
Users can only access their own keystore:
Group Keystore Access
Users can access group keystores if they're a member:
Path Structure
vault/
├── users/
│ ├── john.doe/
│ │ ├── github-token
│ │ ├── aws-credentials
│ │ └── ssh-key
│ └── jane.smith/
│ └── api-key
│
└── groups/
├── platform-team/
│ ├── tfc-token
│ ├── gcp-credentials
│ └── shared-api-key
└── devops/
└── prod-db-password
Configuration
# app-config.yaml
vault:
address: ${VAULT_ADDR}
secretEngine: secret # KV v2 engine path
skipTlsVerify: false # Set true for development
Environment Variables
| Variable | Description | Required |
|---|---|---|
VAULT_ADDR | Vault server address | Yes |
VAULT_TOKEN | Vault token (development) | Dev only |
VAULT_ROLE | GCP IAM role (production) | Prod only |
Security Features
GitHub Team Validation
For group keystores, the backend validates GitHub team membership:
// Teams are extracted from JWT claims
const githubTeams = claims["github.teams"] || [];
// Normalize team names for comparison
const normalizeTeam = (team: string) =>
team.toLowerCase().replace(/[^a-z0-9-]/g, "-");
// Check membership
const hasAccess = githubTeams.some(
(team) => normalizeTeam(team) === normalizeTeam(groupName),
);
Error Messages
Clear, actionable error messages for access issues:
{
"error": "Access Denied",
"message": "You are not a member of the 'platform-team' group",
"yourGroups": ["devops", "engineering"],
"requiredGroup": "platform-team"
}
Debug Endpoints
/debug/jwt
Inspect JWT claims for troubleshooting:
{
"sub": "user:default/john.doe",
"ent": ["group:default/platform-team"],
"github.teams": ["Platform Team", "Engineering"]
}
/debug/config
View non-sensitive configuration:
{
"vaultAddress": "https://vault.example.com",
"secretEngine": "secret",
"authMethod": "gcp-iam"
}
Related Documentation
- Vault Secrets Frontend - Frontend plugin
- Terraform Cloud Backend - Uses Vault for TFC tokens
- Plugins Overview