Federal Information Processing Standard (FIPS) Publication 140-2 is a U.S. government standard that defines minimum security requirements for cryptographic modules in information technology products. Organizations in regulated industries, government agencies, and enterprises with strict security requirements often need to ensure their systems meet FIPS compliance.
FIPS 140-2 compliance ensures that cryptographic operations meet rigorous security standards validated by the National Institute of Standards and Technology (NIST). This is particularly critical for:
Duende IdentityServer is designed as a framework that relies on the underlying platform for cryptographic operations. Specifically, IdentityServer:
When IdentityServer signs tokens or protects cookies, it uses cryptographic modules provided by:
This design ensures better security through well-tested platform implementations, but places the responsibility for FIPS compliance on you.
To build a FIPS-compliant solution with Duende IdentityServer, you are responsible for:
Configure your OS for FIPS mode according to platform requirements:
Choose only FIPS-validated cryptographic algorithms:
Store cryptographic keys in FIPS 140-2 validated modules:
Validate that your entire solution meets FIPS requirements:
Enable FIPS mode in your .NET application following Microsoft's guidance:
public static WebApplication ConfigureServices(this WebApplicationBuilder builder)
{
// Enable FIPS mode
if (builder.Configuration.GetValue<bool>("FIPS:Enabled", false))
{
AppContext.SetSwitch("Switch.System.Security.Cryptography.UseLegacyFipsThrow", false);
Log.Information("FIPS mode enabled for cryptographic operations");
}
// ... rest of your configuration
}
Reference: Microsoft .NET FIPS Compliance Documentation
Configure IdentityServer to use only FIPS-validated algorithms for token signing:
builder.Services.AddIdentityServer(options =>
{
// FIPS-COMPLIANT SIGNING ALGORITHMS ONLY
options.KeyManagement.SigningAlgorithms = new[]
{
// PS256 - FIPS compliant (RSA-PSS with SHA-256)
new SigningAlgorithmOptions(SecurityAlgorithms.RsaSsaPssSha256)
{
UseX509Certificate = true
},
// ES256 - FIPS compliant (ECDSA with P-256 and SHA-256)
new SigningAlgorithmOptions(SecurityAlgorithms.EcdsaSha256)
};
// Additional FIPS-compliant options
options.KeyManagement.SigningAlgorithms = new[]
{
new SigningAlgorithmOptions(SecurityAlgorithms.RsaSsaPssSha256),
new SigningAlgorithmOptions(SecurityAlgorithms.RsaSsaPssSha384),
new SigningAlgorithmOptions(SecurityAlgorithms.RsaSsaPssSha512),
new SigningAlgorithmOptions(SecurityAlgorithms.EcdsaSha256),
new SigningAlgorithmOptions(SecurityAlgorithms.EcdsaSha384),
new SigningAlgorithmOptions(SecurityAlgorithms.EcdsaSha512)
};
});
| Algorithm | FIPS Compliant | IdentityServer Support | Recommended |
|---|---|---|---|
| RS256 | ❌ No | ✅ Yes | ❌ Do not use |
| RS384 | ❌ No | ✅ Yes | ❌ Do not use |
| RS512 | ❌ No | ✅ Yes | ❌ Do not use |
| PS256 | ✅ Yes | ✅ Yes | ✅ Recommended |
| PS384 | ✅ Yes | ✅ Yes | ✅ Recommended |
| PS512 | ✅ Yes | ✅ Yes | ✅ Recommended |
| ES256 | ✅ Yes | ✅ Yes | ✅ Recommended |
| ES384 | ✅ Yes | ✅ Yes | ✅ Recommended |
| ES512 | ✅ Yes | ✅ Yes | ✅ Recommended |
Ensure all client authentication methods use FIPS-compliant algorithms:
builder.Services.AddIdentityServer(options =>
{
// DPoP (Demonstrating Proof-of-Possession) algorithms
options.DPoP.SupportedDPoPSigningAlgorithms = [
SecurityAlgorithms.RsaSsaPssSha256,
SecurityAlgorithms.RsaSsaPssSha384,
SecurityAlgorithms.RsaSsaPssSha512,
SecurityAlgorithms.EcdsaSha256,
SecurityAlgorithms.EcdsaSha384,
SecurityAlgorithms.EcdsaSha512
];
// Client Assertion (JWT Bearer) algorithms
options.SupportedClientAssertionSigningAlgorithms = [
SecurityAlgorithms.RsaSsaPssSha256,
SecurityAlgorithms.RsaSsaPssSha384,
SecurityAlgorithms.RsaSsaPssSha512,
SecurityAlgorithms.EcdsaSha256,
SecurityAlgorithms.EcdsaSha384,
SecurityAlgorithms.EcdsaSha512
];
// Request Object (JAR - JWT Secured Authorization Request) algorithms
options.SupportedRequestObjectSigningAlgorithms = [
SecurityAlgorithms.RsaSsaPssSha256,
SecurityAlgorithms.RsaSsaPssSha384,
SecurityAlgorithms.RsaSsaPssSha512,
SecurityAlgorithms.EcdsaSha256,
SecurityAlgorithms.EcdsaSha384,
SecurityAlgorithms.EcdsaSha512
];
});
ASP.NET Core Data Protection must also use FIPS-compliant algorithms:
using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption;
using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel;
// Configure Data Protection with FIPS-compliant algorithms
builder.Services.AddDataProtection()
.PersistKeysToFileSystem(new DirectoryInfo("/app/dp-keys"))
.UseCryptographicAlgorithms(new AuthenticatedEncryptorConfiguration
{
EncryptionAlgorithm = EncryptionAlgorithm.AES_256_GCM,
ValidationAlgorithm = ValidationAlgorithm.HMACSHA256
});
For production environments, use FIPS 140-2 validated hardware security modules:
using Azure.Identity;
using Azure.Security.KeyVault.Certificates;
builder.Services.AddIdentityServer(options =>
{
// ... other options
})
.AddSigningCredential(async () =>
{
var client = new CertificateClient(
new Uri("https://your-keyvault.vault.azure.net/"),
new DefaultAzureCredential());
var certificate = await client.GetCertificateAsync("signing-cert");
return certificate.Value;
});
Use AWS CloudHSM PKCS#11 provider with IdentityServer for FIPS 140-2 Level 3 compliance.
Deploying IdentityServer in Kubernetes requires additional configuration for FIPS compliance.
Use FIPS-enabled base images:
# Use FIPS-compliant base image
FROM mcr.microsoft.com/dotnet/aspnet:8.0-cbl-mariner2.0
WORKDIR /app
# Create directories for key storage
RUN mkdir -p /app/keys /app/dp-keys && \
chmod 700 /app/keys /app/dp-keys
COPY ./publish .
ENTRYPOINT ["dotnet", "YourIdentityServer.dll"]
Configure persistent storage and environment variables:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: identityserver-keys
spec:
accessModes:
- ReadWriteMany
storageClassName: azurefile # or your storage class
resources:
requests:
storage: 1Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: identityserver
spec:
replicas: 2
selector:
matchLabels:
app: identityserver
template:
metadata:
labels:
app: identityserver
spec:
containers:
- name: identityserver
image: your-registry/identityserver:fips
env:
- name: ASPNETCORE_ENVIRONMENT
value: "Production"
- name: FIPS__Enabled
value: "true"
- name: KeyManagement__KeyPath
value: "/app/keys"
- name: DataProtection__KeyPath
value: "/app/dp-keys"
volumeMounts:
- name: keys
mountPath: /app/keys
- name: dp-keys
mountPath: /app/dp-keys
resources:
requests:
memory: "512Mi"
cpu: "250m"
limits:
memory: "1Gi"
cpu: "500m"
volumes:
- name: keys
persistentVolumeClaim:
claimName: identityserver-keys
- name: dp-keys
persistentVolumeClaim:
claimName: identityserver-keys
Use Azure Workload Identity to access Key Vault from Kubernetes:
apiVersion: v1
kind: ServiceAccount
metadata:
name: identityserver-sa
annotations:
azure.workload.identity/client-id: "<your-managed-identity-client-id>"
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: identityserver
spec:
template:
metadata:
labels:
azure.workload.identity/use: "true"
spec:
serviceAccountName: identityserver-sa
# ... rest of deployment spec
Use appsettings.Production.json for FIPS-specific settings:
{
"FIPS": {
"Enabled": true
},
"KeyManagement": {
"KeyPath": "/app/keys",
"RotationInterval": "3.00:00:00",
"PropagationTime": "1.00:00:00",
"RetentionDuration": "7.00:00:00"
},
"DataProtection": {
"KeyPath": "/app/dp-keys"
}
}
Configure appropriate key rotation and retention:
builder.Services.AddIdentityServer(options =>
{
// Rotate signing keys every 3 days
options.KeyManagement.RotationInterval = TimeSpan.FromDays(3);
// Announce new key 1 day in advance in discovery
options.KeyManagement.PropagationTime = TimeSpan.FromDays(1);
// Keep old key for 7 days for token validation
options.KeyManagement.RetentionDuration = TimeSpan.FromDays(7);
// Use persistent storage path
var keyPath = builder.Configuration.GetValue<string>("KeyManagement:KeyPath")
?? "/app/keys";
options.KeyManagement.KeyPath = keyPath;
});
Implement a health check to verify FIPS mode is enabled:
app.MapGet("/health/fips", () =>
{
var isFipsEnabled = AppContext.TryGetSwitch(
"Switch.System.Security.Cryptography.UseLegacyFipsThrow",
out var enabled) && !enabled;
return Results.Ok(new
{
fipsMode = isFipsEnabled,
signingAlgorithms = new[] { "PS256", "ES256", "PS384", "ES384", "PS512", "ES512" },
environment = app.Environment.EnvironmentName
});
}).AllowAnonymous();
Verify the discovery endpoint only advertises FIPS-compliant algorithms:
# Check discovery endpoint
curl https://your-identityserver.com/.well-known/openid-configuration | jq .id_token_signing_alg_values_supported
# Expected output (FIPS-compliant):
# ["PS256", "ES256", "PS384", "ES384", "PS512", "ES512"]
# Should NOT include:
# ["RS256", "RS384", "RS512"]
When migrating to FIPS-compliant algorithms, consider client compatibility:
If you currently use RS256 and need to migrate:
// Transition period (NOT FIPS-compliant, but allows migration)
options.KeyManagement.SigningAlgorithms = new[]
{
new SigningAlgorithmOptions(SecurityAlgorithms.RsaSsaPssSha256),
new SigningAlgorithmOptions(SecurityAlgorithms.EcdsaSha256),
new SigningAlgorithmOptions(SecurityAlgorithms.RsaSha256) // Remove after migration
};
Most modern OAuth 2.0 client libraries support PS256 and ES256:
| Library | PS256 Support | ES256 Support |
|---|---|---|
| IdentityModel (C#) | ✅ Yes | ✅ Yes |
| MSAL (Microsoft) | ✅ Yes | ✅ Yes |
| AppAuth (iOS/Android) | ✅ Yes | ✅ Yes |
| Passport.js (Node) | ✅ Yes | ✅ Yes |
| Spring Security | ✅ Yes | ✅ Yes |
Problem: After configuration change, old signing keys still use RS256.
Solution:
RetentionDuration temporarily during migrationProblem: Clients fail to validate tokens with PS256/ES256.
Solution:
Problem: Application loses session state after pod restart.
Solution:
Problem: IdentityServer cannot access certificates in Key Vault.
Solution:
FIPS compliance is one layer of security. Also implement:
Configure TLS to use only FIPS-compliant cipher suites:
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureHttpsDefaults(httpsOptions =>
{
httpsOptions.SslProtocols = SslProtocols.Tls12 | SslProtocols.Tls13;
// Additional FIPS-compliant TLS configuration
});
});
Establish and document key rotation procedures:
Maintain documentation for compliance audits:
Implement comprehensive logging:
builder.Services.AddIdentityServer(options =>
{
// Enable comprehensive event logging
options.Events.RaiseErrorEvents = true;
options.Events.RaiseInformationEvents = true;
options.Events.RaiseFailureEvents = true;
options.Events.RaiseSuccessEvents = true;
});
As quantum computing advances, cryptographic algorithms face new challenges. The cryptographic community is preparing for this transition:
While FIPS 140-2 currently validates classical algorithms, organizations should:
NIST is updating to FIPS 140-3, which will eventually include post-quantum algorithms:
When implementing FIPS compliance with Duende IdentityServer: