Modern applications depend on numerous secrets, including database connection strings, API keys, OAuth client credentials, encryption keys, certificates, and cloud access tokens. Managing these secrets securely is essential because hardcoded credentials, exposed environment variables, or improperly configured CI/CD pipelines can become entry points for attackers.
In cloud-native environments, secrets often move through multiple systems—from development machines to CI/CD pipelines, Kubernetes clusters, and production applications. A secure secrets management strategy ensures that sensitive information remains protected throughout the entire software delivery lifecycle.
In this article, you'll learn how to build an enterprise secrets management architecture using Azure Key Vault, Kubernetes, and GitHub Actions, along with practical best practices for securing modern .NET applications.
Why Secrets Management Matters
Applications commonly require access to:
Storing these values directly in source code or configuration files creates unnecessary security risks.
Typical Enterprise Architecture
A secure deployment might look like this:
Developer
|
GitHub Repository
|
GitHub Actions
|
Azure Key Vault
|
Kubernetes Cluster
|
ASP.NET Core Application
Secrets are retrieved securely during deployment rather than being stored in the application repository.
Common Security Risks
Poor secrets management can lead to:
| Risk | Example |
|---|
| Hardcoded credentials | Password committed to Git |
| Shared secrets | Same API key across environments |
| Expired certificates | Application outage |
| Excessive permissions | Unnecessary administrative access |
| Secret leakage | Credentials exposed in logs |
Reducing these risks requires centralized secret management.
Azure Key Vault Overview
Azure Key Vault securely stores:
Secrets
Certificates
Cryptographic keys
Applications retrieve secrets at runtime instead of embedding them in configuration files.
Example architecture:
Application
|
Azure Key Vault
|
Secrets
This approach improves both security and operational flexibility.
Creating a Key Vault Client
Install the required package.
dotnet add package Azure.Security.KeyVault.Secrets
Create a client.
using Azure.Identity;
using Azure.Security.KeyVault.Secrets;
var client =
new SecretClient(
new Uri(vaultUrl),
new DefaultAzureCredential());
DefaultAzureCredential allows applications to authenticate using supported Azure identity mechanisms.
Retrieving a Secret
Access a stored secret.
KeyVaultSecret secret =
await client.GetSecretAsync(
"DatabaseConnection");
Applications should retrieve secrets only when necessary and avoid logging sensitive values.
Using Configuration Providers
ASP.NET Core can integrate secrets into configuration.
builder.Configuration
.AddAzureKeyVault(
new Uri(vaultUrl),
new DefaultAzureCredential());
This enables applications to access secrets through the standard configuration API.
Secrets in Kubernetes
Kubernetes provides a Secret resource for storing sensitive values.
Example:
apiVersion: v1
kind: Secret
metadata:
name: app-secret
type: Opaque
data:
connectionString: BASE64_VALUE
Applications reference the secret rather than embedding credentials inside container images.
Base64 encoding is not encryption. Additional protections such as encryption at rest and access controls should be used where supported.
Consuming Kubernetes Secrets
Mount a secret as an environment variable.
env:
- name: ConnectionString
valueFrom:
secretKeyRef:
name: app-secret
key: connectionString
This keeps sensitive values outside application code.
Synchronizing Azure Key Vault and Kubernetes
Many organizations centralize secrets in Azure Key Vault while allowing Kubernetes workloads to consume them.
Azure Key Vault
|
Secret Synchronization
|
Kubernetes Secret
|
Application
This reduces duplication while keeping Key Vault as the authoritative source.
GitHub Actions and Secrets
CI/CD pipelines also require credentials.
GitHub Actions stores sensitive values separately from workflow files.
Workflow example:
env:
API_KEY:
${{ secrets.API_KEY }}
Using repository or organization secrets prevents credentials from being committed to source control.
Deploying Without Hardcoding Credentials
A deployment workflow might look like this:
GitHub Actions
|
Authenticate
|
Retrieve Secrets
|
Deploy Application
Credentials remain outside the application repository throughout the deployment process.
Secret Rotation
Long-lived credentials increase security risk.
A recommended lifecycle:
Create Secret
|
Use Secret
|
Rotate Secret
|
Update Applications
Applications should be designed to handle secret rotation with minimal disruption.
Principle of Least Privilege
Applications should receive only the permissions they require.
Instead of:
Application
Full Key Vault Access
Use:
Application
Read Database Secret
Read Storage Secret
Restricting access reduces the impact of compromised identities.
Avoid Logging Secrets
Never log sensitive values.
Avoid:
logger.LogInformation(
connectionString);
Prefer:
logger.LogInformation(
"Database connection initialized.");
Operational logs should contain metadata rather than confidential information.
Monitoring Secret Usage
Useful operational metrics include:
Monitoring helps identify configuration issues and potential security incidents.
Production Architecture
A typical production deployment:
Developer
|
GitHub Actions
|
Azure Key Vault
|
Kubernetes
|
ASP.NET Core API
|
Database
Each component retrieves only the secrets it requires.
Production Best Practices
| Practice | Benefit |
|---|
| Store secrets centrally | Simplified management |
| Retrieve secrets at runtime | Reduce exposure |
| Apply least privilege | Limit access |
| Rotate secrets regularly | Lower long-term risk |
| Avoid hardcoded credentials | Better security |
| Audit secret access | Improved compliance |
| Monitor authentication failures | Faster incident detection |
Common Mistakes
| Mistake | Better Approach |
|---|
| Committing secrets to Git | Use Key Vault or GitHub Secrets |
| Reusing credentials across environments | Use separate secrets for each environment |
| Granting broad permissions | Apply least privilege |
| Logging secret values | Log operational events only |
| Ignoring secret rotation | Rotate credentials regularly |
| Storing secrets in container images | Retrieve them during deployment or runtime |
Troubleshooting
Application cannot retrieve secrets
Verify:
Kubernetes pod fails to start
Check:
GitHub Actions deployment fails
Review:
Secret rotation causes failures
Investigate:
Secret Storage Comparison
| Feature | Azure Key Vault | Kubernetes Secrets | GitHub Secrets |
|---|
| Primary Purpose | Central secret management | Runtime application secrets | CI/CD pipeline secrets |
| Rotation Support | Yes | Depends on implementation | Manual or automated workflows |
| Access Control | Fine-grained | Kubernetes RBAC | Repository and organization permissions |
| Best Use | Production secrets | Container workloads | Build and deployment pipelines |
These technologies complement one another rather than competing. Many enterprise environments use all three together.
Frequently Asked Questions
Should secrets ever be stored in source code?
No. Sensitive information should be stored in dedicated secret management systems rather than application code or configuration files committed to source control.
Is Base64 encoding sufficient protection for Kubernetes Secrets?
No. Base64 encoding is an encoding mechanism, not encryption. Protect Kubernetes Secrets with appropriate access controls and, where available, encryption at rest.
Why use Azure Key Vault if Kubernetes already supports Secrets?
Azure Key Vault provides centralized management, auditing, access control, and secret lifecycle management. Kubernetes Secrets are commonly used to deliver those secrets securely to running workloads.
Should development and production use the same secrets?
No. Each environment should have its own independent credentials to reduce risk and simplify access management.
How often should secrets be rotated?
Rotation frequency depends on organizational policies, regulatory requirements, and the sensitivity of the secret. Critical credentials should be reviewed and rotated according to established security practices.
Conclusion
Enterprise applications rely on secrets throughout their entire lifecycle, from development and CI/CD pipelines to container orchestration and production services. A secure secrets management strategy requires more than simply hiding credentials—it requires centralized storage, controlled access, regular rotation, auditing, and integration with deployment workflows.
By combining Azure Key Vault for centralized secret management, Kubernetes for secure runtime delivery, and GitHub Actions for protected CI/CD automation, organizations can build a layered approach that improves security, simplifies operations, and reduces the risk of credential exposure across modern cloud-native .NET applications.