
August 22, 2026
12 min read
By Kokil Thapa | Last reviewed: September 2026
Google ranks this page for one question above all others: what are the differences between keys, secrets, and certificates inside Azure Key Vault. Teams that treat the vault as a single password bucket pick the wrong object type, grant overly broad RBAC roles, and expose private keys during certificate reads. Azure cloud adoption for Nepal-based businesses often starts with moving credentials out of Git and unencrypted .env files — and Key Vault is the standard place to put them. This guide answers the comparison first, then covers permissions, PHP SecretClient integration in Laravel, and production rotation patterns.
Microsoft documents these three object families under separate REST paths: /keys, /secrets, and /certificates. Each has distinct RBAC roles, SDK clients, and lifecycle rules. Confusing them is the most common Key Vault misconfiguration I see on production PHP deployments.
What Are the Differences Between Keys, Secrets, and Certificates in Azure Key Vault?
Azure Key Vault is one service with three managed object types. They share a vault URI and authentication layer, but they behave differently at the API, permission, and security level.
Keys are asymmetric or symmetric cryptographic assets. You send plaintext or ciphertext to the vault; the private key never leaves the HSM in a Premium SKU vault. Supported operations include encrypt, decrypt, sign, verify, wrapKey, and unwrapKey. Use keys when losing the raw private material would be catastrophic — column-level encryption, JWT signing with RS256, or Azure Disk Encryption.
Secrets are opaque strings up to 25 KB. Authorized callers retrieve the plaintext value directly. Every update creates a new version; older versions remain addressable by version ID. This is where database passwords, Stripe keys, Khalti merchant tokens, and OAuth client secrets belong. On legal-tech portals I've built, payment gateway credentials live here instead of committed .env files.
Certificates are X.509 objects with optional lifecycle automation. Key Vault can issue self-signed certs or integrate with CAs like DigiCert. A certificate object bundles the public cert, private key, and optional CSR. Retrieving a certificate via the default API returns the private key — a detail many teams miss during audits.
The official Microsoft overview at Azure Key Vault documentation defines these boundaries. Your application SDK must match the object type: azure/security-keyvault-keys, azure/security-keyvault-secrets, or azure/security-keyvault-certificates.
| Attribute | Keys | Secrets | Certificates |
|---|---|---|---|
| Primary purpose | Cryptographic operations in-vault | Store arbitrary sensitive strings | TLS identity + lifecycle |
| Private material export | Non-exportable (HSM Premium) | Full plaintext on read | Private key returned on cert read |
| Versioning | Yes — each key update | Yes — each secret update | Yes — each renewal |
| Typical RBAC role | Key Vault Crypto User | Key Vault Secrets User | Key Vault Certificates User |
| REST path | /keys/{name} | /secrets/{name} | /certificates/{name} |
| Rate limit (Standard tier) | 2,000 ops/sec | 2,000 reads/sec | Shared vault throughput |
How Do You Choose Between Azure Key Vault Keys vs Secrets vs Certificates?
The decision is not about sensitivity alone. All three protect sensitive material. The question is whether your app needs crypto operations, plain text retrieval, or TLS lifecycle management.
- Choose a Secret when you need a connection string, API bearer token, or third-party OAuth client secret. No in-vault crypto operation is required.
- Choose a Key when the app encrypts data, signs tokens, or wraps other keys — and the private key must never appear in logs or memory dumps as an exportable PEM file.
- Choose a Certificate when you terminate TLS, authenticate to Azure services via client cert, or need automated renewal from a CA integration.
A concrete example: storing a JWT RS256 private key as a Secret lets any principal with read access download the PEM. Storing it as a Key with Key Vault Crypto User permissions allows signing via API only. Auditors flag the Secret approach every time.
On a client portal project similar to Mijar Law Associates, document encryption keys belong in the Keys store. Khalti and eSewa merchant IDs belong in Secrets. Public-facing TLS for App Service belongs in Certificates — or better, let App Service manage TLS and keep internal service-to-service certs in the vault.
Cost matters for small teams. A Standard vault runs roughly USD 0.03 per 10,000 secret operations (~Rs 4 at typical 2026 exchange rates). Premium HSM-backed keys cost more — budget Rs 3,000–8,000/month (~USD 22–60) for a modest multi-environment setup. See budgeting Azure in NPR for Nepal startups for broader cloud cost planning.
How Do You Configure RBAC Permissions for Azure Key Vault Keys, Secrets, and Certificates?
Azure RBAC replaced legacy access policies as the recommended permission model. Assign data-plane roles scoped to the vault resource — never subscription-wide Contributor for runtime apps.
Built-in roles you actually need
# Production app — read secrets only
az role assignment create \
--role "Key Vault Secrets User" \
--assignee <managed-identity-object-id> \
--scope "/subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.KeyVault/vaults/<vault>"
# CI/CD pipeline — rotate secrets
az role assignment create \
--role "Key Vault Secrets Officer" \
--assignee <pipeline-sp-object-id> \
--scope "/subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.KeyVault/vaults/<vault>"
# App that signs JWTs in-vault — no key export
az role assignment create \
--role "Key Vault Crypto User" \
--assignee <managed-identity-object-id> \
--scope "/subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.KeyVault/vaults/<vault>" Common gotcha: Key Vault Administrator grants full control including delete and purge. Never assign it to application identities. Separate vaults per environment (dev, staging, prod) beats one vault with complex RBAC for most small teams.
Enable diagnostic logs to Log Analytics or Microsoft Sentinel. You cannot detect credential abuse without auditing SecretGet, KeySign, and CertificateGet events. Pair this with Git secrets scanning in CI so leaked credentials never reach production twice.
How Do You Use SecretClient in PHP with Laravel?
The search query azure\security\keyvault\secrets\secretclient maps directly to the official PHP SDK. Laravel 12.x and 13.x on PHP 8.3+ integrate cleanly via Composer 2.10. Avoid unmaintained community wrappers — the Azure Identity v2 credential chain changed authentication behaviour significantly.
Install and bind the client
- Install packages:
composer require azure/identity azure/security-keyvault-secrets - Enable System-Assigned Managed Identity on Azure App Service or AKS workload.
- Assign Key Vault Secrets User to that identity on the vault scope.
- Register
SecretClientas a singleton and cache reads in Redis.
// app/Providers/AppServiceProvider.php
use Azure\Identity\DefaultAzureCredential;
use Azure\Security\KeyVault\Secrets\SecretClient;
public function register(): void
{
$this->app->singleton(SecretClient::class, function () {
return new SecretClient(
vaultUrl: config('services.azure.keyvault.url'),
credential: new DefaultAzureCredential()
);
});
}
// app/Support/VaultSecrets.php
use Illuminate\Support\Facades\Cache;
function vaultSecret(string $name, ?string $version = null): string
{
$cacheKey = $version ? "vault:{$name}:{$version}" : "vault:{$name}:latest";
return Cache::remember($cacheKey, 3600, function () use ($name, $version) {
$client = app(SecretClient::class);
$secret = $version
? $client->getSecret($name, $version)
: $client->getSecret($name);
return $secret->getValue();
});
} DefaultAzureCredential tries Managed Identity in Azure, then Azure CLI locally, then environment variables. Set AZURE_TENANT_ID in local .env to avoid ambiguous auth errors. Never commit AZURE_CLIENT_SECRET to Git — use az login for local dev instead.
Rate limits hit fast during boot if every config value triggers a vault call. Fetch once per request cycle or cache in Redis with a 30–60 minute TTL. Invalidate cache immediately after rotation. For API design patterns around credential handling, see Laravel API best practices and OAuth security best practices.
For signing operations, swap in azure/security-keyvault-keys and call $client->sign() instead of reading key material. For TLS assets, use CertificateClient. Mixing clients is normal — one vault, three SDK entry points.
When Should You Use Keys vs Secrets vs Certificates in Production Architectures?
Production decisions should survive a security audit and a 3 a.m. rotation incident. This table covers scenarios I encounter on enterprise application projects and API platforms.
| Scenario | Correct type | Why not the others? |
|---|---|---|
| MySQL password, Stripe API key | Secret | Keys cannot store arbitrary text; Certificates add X.509 overhead |
| Encrypting PII columns at rest | Key (RSA-OAEP) | Secrets lack crypto ops; export risk is too high |
| Internal mTLS between microservices | Certificate | Auto-renewal and issuer integration beat manual PEM files |
| Signing JWTs for API auth | Key (RS256/ES256) | Secret storage allows PEM download and log exposure |
| OAuth client secret for SaaS API | Secret | Bearer token, not cryptographic key material |
| Azure VM disk encryption | Key (RSA-HSM) | Requires non-exportable HSM-backed key |
| Webhook HMAC shared secret | Secret | Symmetric string used in application code directly |
Edge case: storing a PEM file as a Secret works until an auditor asks why the private key is downloadable. Edge case two: reading a Certificate returns the private key by default — scope Certificates User carefully. Edge case three: Key Vault is a dependency. Cache secrets locally in Redis and implement graceful degradation so a transient Azure outage does not take down your entire app.
Compare with multi-cloud secrets management if you also run AWS Secrets Manager or HashiCorp Vault. Key Vault fits naturally when the app already lives on Azure App Service, AKS, or Azure DevOps pipelines.
How Do You Handle Secret Rotation and Disaster Recovery in Azure Key Vault?
Rotation breaks production when teams overwrite the current version instead of creating a new one. Key Vault versioning exists precisely to prevent that failure mode.
Zero-downtime rotation workflow
- Create version N+1 alongside the active version N. Both remain valid.
- Update downstream systems — database users, third-party dashboards, webhooks.
- Switch the app to version N+1 or clear cache so
latestresolves correctly. - Monitor error rates for 15–30 minutes. Keep version N enabled as fallback.
- Disable version N after stability is confirmed. Never hard-delete immediately.
Certificates support automated renewal policies with integrated CAs. Secrets require a scheduled job or pipeline step — Azure DevOps, GitHub Actions, or a Laravel scheduled command. For pipeline integration patterns, see Azure DevOps YAML pipelines and workload identity federation without long-lived keys.
Disaster recovery requires soft-delete (enabled by default) and purge protection. Without purge protection, a compromised admin can permanently destroy secrets. Set retention to 90 days minimum. Key Vault does not geo-replicate automatically — copy critical secrets to a secondary vault in another region for multi-region apps.
Generate strong rotation values with a password generator during manual rotations. Store the generation script in Git, not the secret itself. Scan repos with Gitleaks before every deploy.
Test rotation quarterly in staging. A rotation procedure that exists only in documentation will fail the first time you need it under pressure. Align with database encryption at rest and in transit policies if you encrypt columns with a vault key.
Key Takeaways
- Keys perform in-vault crypto ops; Secrets store retrievable text; Certificates manage X.509 TLS lifecycles — three APIs, three RBAC roles.
- Never store JWT signing private keys or disk encryption keys as Secrets — use Keys with Crypto User permissions instead.
- In Laravel, bind
Azure\Security\KeyVault\Secrets\SecretClient, authenticate via Managed Identity, and cache reads in Redis. - Assign least-privilege RBAC per object type — Secrets User for apps, Secrets Officer for CI/CD only.
- Rotate by creating new versions, not overwriting — keep the old version as rollback until stability is confirmed.
- Enable soft-delete, purge protection, and diagnostic logging — you cannot audit what you cannot observe.
People Also Ask
Can I store a private key as an Azure Key Vault secret?
Technically yes — a PEM string fits in a Secret. Security-wise, no. Anyone with Secrets User can download the full private key. Store signing and encryption keys as Key objects and call crypto operations via the API instead.
Does reading an Azure Key Vault certificate expose the private key?
Yes, by default. A standard getCertificate call returns the full bundle including the private key. Request only the public certificate if your app does not need the private material. Scope Certificates User narrowly.
What is the difference between Azure Key Vault Standard and Premium?
Standard vaults store keys in software. Premium vaults back keys with HSM hardware — private key material is non-exportable. Use Premium for regulatory requirements, disk encryption, and high-value signing keys. Secrets and certificates work on both tiers.
How do I access Azure Key Vault from Laravel locally?
Install the PHP SDK, run az login, and let DefaultAzureCredential pick up your CLI session. Set AZURE_TENANT_ID in .env. Do not put client secrets in Git — use Managed Identity in Azure and CLI auth locally.
Build Secure Credential Management Into Your Stack
Understanding what are the differences between keys, secrets, and certificates is the first step. The second is migrating credentials out of Git, enforcing least-privilege RBAC, and testing rotation before an audit forces it. Start with payment gateway tokens and database passwords — highest blast radius, fastest win.
Key Vault pairs naturally with API development, Azure App Service deployments, and Laravel OWASP hardening. If you need help wiring SecretClient into a production PHP app or reviewing an existing vault configuration, reach out through my contact page or request a consultation. Strong secret management is baseline infrastructure — not a feature you add after launch.
Frequently Asked Questions
0 Comments
Leave a comment
Your email is not published. Comments appear once they have been read. Sign in to have your details filled in.

