Skip to content

Commit 99dd6fb

Browse files
committed
Moved data protection info to a new page in the General Information section. Added callouts for BFF. Updated the Data Protection info for IdentityServer to link to the general topic.
1 parent 1c0520d commit 99dd6fb

2 files changed

Lines changed: 135 additions & 101 deletions

File tree

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
---
2+
title: Data Protection
3+
description: Comprehensive guide covering key aspects of add data protection.
4+
date: 2026-03-26T08:20:20+02:00
5+
sidebar:
6+
order: 20
7+
redirect_from:
8+
- /dataprotection/
9+
---
10+
11+
Any Duende server-side application like IdentityServer of BFF is developed and deployed as an ASP.NET Core application. While there are a lot of decisions to make, this also means that your implementation can be built, deployed, hosted, and managed with the same technology you're using for any other ASP.NET applications you have.
12+
13+
One important aspect to include in your application is around Data Protection.
14+
15+
:::note
16+
Some of our most common support requests are related to [Data Protection Keys](#data-protection-keys), so we strongly encourage you to review the rest of this page before deploying to production.
17+
:::
18+
19+
## ASP.NET Core Data Protection
20+
21+
Data Protection in any Duende server-side application makes extensive use of ASP.NET's [data protection](https://docs.microsoft.com/en-us/aspnet/core/security/data-protection/) feature. It is crucial that you configure data protection correctly before you start using your application in production.
22+
23+
In local development, ASP.NET automatically creates data protection keys, but in a deployed environment, you will need
24+
to ensure that your data protection keys are stored in a persistent way and shared across all load balanced instances of
25+
your implementation. This means you'll need to choose where to store and how to protect the data
26+
protection keys, as appropriate for your environment. Microsoft has extensive
27+
documentation [here](https://learn.microsoft.com/en-us/aspnet/core/security/data-protection/configuration/overview)
28+
describing how to configure storage and protection of data protection keys.
29+
30+
A typical implementation should include data protection configuration code, like this:
31+
32+
```csharp
33+
// Program.cs
34+
builder.Services.AddDataProtection()
35+
// Choose an extension method for key persistence, such as
36+
// PersistKeysToFileSystem, PersistKeysToDbContext,
37+
// PersistKeysToAzureBlobStorage, PersistKeysToAWSSystemsManager, or
38+
// PersistKeysToStackExchangeRedis
39+
.PersistKeysToFoo()
40+
// Choose an extension method for key protection, such as
41+
// ProtectKeysWithCertificate, ProtectKeysWithAzureKeyVault
42+
.ProtectKeysWithBar()
43+
// Explicitly set an application name to prevent issues with
44+
// key isolation.
45+
.SetApplicationName("My.Duende.IdentityServer");
46+
```
47+
48+
:::danger[Ensure data protection keys are persisted]
49+
Always make sure data protection is configured to persist data protection keys to storage, using `.PersistKeys...()`
50+
for your storage mechanism.
51+
52+
In addition, make sure the storage mechanism itself is durable. For example, if you are using the default file system
53+
based key store, make sure that the configured path is not stored on ephemeral storage. If you are using Redis to store
54+
data protection keys using `PersistKeysToStackExchangeRedis`, ensure that your Redis service is configured to persist
55+
data to a database backup or append-only file. Otherwise, when your Redis instance reboots, you will lose all data
56+
protection keys.
57+
58+
If you lose your data protection keys, all data protected with those keys is no longer be readable.
59+
:::
60+
61+
## ASP.NET Data Protection Keys and IdentityServer Signing Keys
62+
63+
ASP.NET's data protection keys are sometimes confused with IdentityServer's signing keys, but the two are completely
64+
separate keys with different purposes. IdentityServer implementations need both to function correctly.
65+
66+
### ASP.NET Data Protection Keys
67+
68+
Data protection is a cryptographic library that is part of ASP.NET Core. Data protection uses private key
69+
cryptography to encrypt and sign sensitive data to ensure that it is only written and read by the application. The
70+
framework uses data protection to secure data that is commonly used by IdentityServer implementations, such as
71+
authentication cookies and anti-forgery tokens. In addition, IdentityServer itself uses data protection to protect
72+
sensitive data at rest, such as persisted grants, and sensitive data passed through the browser, such as the
73+
context objects passed to pages in the UI. The data protection keys are critical secrets for an IdentityServer
74+
implementation because they encrypt a great deal of sensitive data at rest and prevent sensitive data that is
75+
round-tripped through the browser from being tampered with.
76+
77+
### The IdentityServer Signing Key
78+
79+
Separately, IdentityServer needs cryptographic keys, called [signing keys](/identityserver/fundamentals/key-management.md), to
80+
sign tokens such as JWT access tokens and id tokens. The signing keys use public key cryptography to allow client
81+
applications and APIs to validate token signatures using the public keys, which are published by IdentityServer
82+
through [discovery](/identityserver/reference/endpoints/discovery.md). The private key component of the signing keys are
83+
also critical secrets for IdentityServer because a valid signature provides integrity and non-repudiation guarantees
84+
that allow client applications and APIs to trust those tokens.
85+
86+
## Common Problems
87+
88+
Common data protection problems occur when data is protected with a key that is not available when the data is later
89+
read. A common symptom is `CryptographicException`s in the application logs. For example, when automatic key
90+
management fails to read its signing keys due to a data protection failure, IdentityServer will log an error message
91+
such as "Error unprotecting key with kid {Signing Key ID}.", and log the underlying
92+
`System.Security.Cryptography.CryptographicException`, with a message like "The key {Data Protection Key ID} was not
93+
found in the key ring."
94+
95+
Failures to read automatic signing keys are often the first place where a data protection problem manifests, but any of
96+
many places where ASP.NET uses data protection might also throw `CryptographicException`s.
97+
98+
There are several ways that data protection problems can occur:
99+
100+
1. In load balanced environments, every instance of a Duende server-side app needs to be configured to share data protection keys.
101+
Without shared data protection keys, each load balanced instance will only be able to read the data that it writes.
102+
2. Data protected data could be generated in a development environment and then accidentally included into the build
103+
output. This is most commonly the case for automatically managed signing keys that are stored on disk. If you are
104+
using automatic signing key management with the default file system based key store, you should exclude the `~/keys`
105+
directory from source control and make sure keys are not included in your builds. Note that if you are using our
106+
Entity Framework based implementation of the operational data stores, then the keys will instead be stored in the
107+
database.
108+
3. Data protection creates keys isolated by application name. If you don't specify a name, the content root path of the
109+
application will be used. But, beginning in .NET 6.0 Microsoft changed how they handle the path, which can cause data
110+
protection keys to break. Their docs on the problem
111+
are [here](https://learn.microsoft.com/en-us/aspnet/core/security/data-protection/configuration/overview#setapplicationname),
112+
including a work-around where you de-normalize the path. Then, in .NET 7.0, this change was reverted. The solution is
113+
always to specify an explicit application name, and if you have old keys that were generated without an explicit
114+
application name, you need to set your application name to match the default behavior that produced the keys you want
115+
to be able to read.
116+
4. If your IdentityServer is hosted by IIS, special configuration is needed for data protection. In most default
117+
deployments, IIS lacks the permissions required to persist data protection keys, and falls back to using an ephemeral
118+
key generated every time the site starts up. Microsoft's docs on this issue
119+
are [here](https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/iis/advanced?view=aspnetcore-7.0#data-protection).
120+
121+
### Identity Server's Usage of Data Protection
122+
123+
Duende IdentityServer's features that rely on data protection include
124+
125+
* protecting signing keys at rest (if [automatic key management](/identityserver/fundamentals/key-management.md#automatic-key-management) is used and enabled)
126+
* protecting [persisted grants](/identityserver/data/operational.md#persisted-grant-service) at rest (if enabled)
127+
* protecting [server-side session](/identityserver/ui/server-side-sessions/index.md) data at rest (if enabled)
128+
* protecting [the state parameter](/identityserver/ui/login/external.md#state-url-length-and-isecuredataformat) for
129+
external OIDC providers (if enabled)
130+
* protecting message payloads sent between pages in the UI (
131+
e.g. [logout context](/identityserver/ui/logout/logout-context.md) and [error context](/identityserver/ui/error.md)).
132+
* session management (because the ASP.NET Core cookie authentication handler requires it)

astro/src/content/docs/identityserver/deployment/index.md

Lines changed: 3 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ sidebar:
66
label: Overview
77
order: 10
88
redirect_from:
9-
- /dataprotection/
109
- /identityserver/v5/deployment/
1110
- /identityserver/v6/deployment/
1211
- /identityserver/v7/deployment/
@@ -96,116 +95,19 @@ Duende IdentityServer makes extensive use of
9695
ASP.NET's [data protection](https://docs.microsoft.com/en-us/aspnet/core/security/data-protection/) feature. It is
9796
crucial that you configure data protection correctly before you start using your IdentityServer in production.
9897

99-
In local development, ASP.NET automatically creates data protection keys, but in a deployed environment, you will need
100-
to ensure that your data protection keys are stored in a persistent way and shared across all load balanced instances of
101-
your IdentityServer implementation. This means you'll need to choose where to store and how to protect the data
102-
protection keys, as appropriate for your environment. Microsoft has extensive
103-
documentation [here](https://learn.microsoft.com/en-us/aspnet/core/security/data-protection/configuration/overview)
104-
describing how to configure storage and protection of data protection keys.
98+
The recommended practices for setting up and using Data Protection in Duende IdentityServer are the same as other server-side products, like BFF, and are enumerated in the [general Data Protection page](/general/data-protection).
10599

106-
A typical IdentityServer implementation should include data protection configuration code, like this:
107-
108-
```csharp
109-
// Program.cs
110-
builder.Services.AddDataProtection()
111-
// Choose an extension method for key persistence, such as
112-
// PersistKeysToFileSystem, PersistKeysToDbContext,
113-
// PersistKeysToAzureBlobStorage, PersistKeysToAWSSystemsManager, or
114-
// PersistKeysToStackExchangeRedis
115-
.PersistKeysToFoo()
116-
// Choose an extension method for key protection, such as
117-
// ProtectKeysWithCertificate, ProtectKeysWithAzureKeyVault
118-
.ProtectKeysWithBar()
119-
// Explicitly set an application name to prevent issues with
120-
// key isolation.
121-
.SetApplicationName("IdentityServer");
122-
```
123-
124-
:::danger[Ensure data protection keys are persisted]
125-
Always make sure data protection is configured to persist data protection keys to storage, using `.PersistKeys...()`
126-
for your storage mechanism.
127-
128-
In addition, make sure the storage mechanism itself is durable. For example, if you are using the default file system
129-
based key store, make sure that the configured path is not stored on ephemeral storage. If you are using Redis to store
130-
data protection keys using `PersistKeysToStackExchangeRedis`, ensure that your Redis service is configured to persist
131-
data to a database backup or append-only file. Otherwise, when your Redis instance reboots, you will lose all data
132-
protection keys.
133-
134-
If you lose your data protection keys, all data protected with those keys to no longer be readable.
135-
:::
136-
137-
### Data Protection Keys and IdentityServer's Signing Keys
138-
139-
ASP.NET's data protection keys are sometimes confused with IdentityServer's signing keys, but the two are completely
140-
separate keys with different purposes. IdentityServer implementations need both to function correctly.
141-
142-
#### Data Protection Keys
143-
144-
Data protection is a cryptographic library that is part of the ASP.NET framework. Data protection uses private key
145-
cryptography to encrypt and sign sensitive data to ensure that it is only written and read by the application. The
146-
framework uses data protection to secure data that is commonly used by IdentityServer implementations, such as
147-
authentication cookies and anti-forgery tokens. In addition, IdentityServer itself uses data protection to protect
148-
sensitive data at rest, such as persisted grants, and sensitive data passed through the browser, such as the
149-
context objects passed to pages in the UI. The data protection keys are critical secrets for an IdentityServer
150-
implementation because they encrypt a great deal of sensitive data at rest and prevent sensitive data that is
151-
round-tripped through the browser from being tampered with.
152-
153-
#### IdentityServer Signing Key
154-
155-
Separately, IdentityServer needs cryptographic keys, called [signing keys](/identityserver/fundamentals/key-management.md), to
156-
sign tokens such as JWT access tokens and id tokens. The signing keys use public key cryptography to allow client
157-
applications and APIs to validate token signatures using the public keys, which are published by IdentityServer
158-
through [discovery](/identityserver/reference/endpoints/discovery.md). The private key component of the signing keys are
159-
also critical secrets for IdentityServer because a valid signature provides integrity and non-repudiation guarantees
160-
that allow client applications and APIs to trust those tokens.
161-
162-
### Common Problems
163-
164-
Common data protection problems occur when data is protected with a key that is not available when the data is later
165-
read. A common symptom is `CryptographicException`s in the IdentityServer logs. For example, when automatic key
166-
management fails to read its signing keys due to a data protection failure, IdentityServer will log an error message
167-
such as "Error unprotecting key with kid {Signing Key ID}.", and log the underlying
168-
`System.Security.Cryptography.CryptographicException`, with a message like "The key {Data Protection Key ID} was not
169-
found in the key ring."
170-
171-
Failures to read automatic signing keys are often the first place where a data protection problem manifests, but any of
172-
many places where IdentityServer and ASP.NET use data protection might also throw `CryptographicException`s.
173-
174-
There are several ways that data protection problems can occur:
175-
176-
1. In load balanced environments, every instance of IdentityServer needs to be configured to share data protection keys.
177-
Without shared data protection keys, each load balanced instance will only be able to read the data that it writes.
178-
2. Data protected data could be generated in a development environment and then accidentally included into the build
179-
output. This is most commonly the case for automatically managed signing keys that are stored on disk. If you are
180-
using automatic signing key management with the default file system based key store, you should exclude the `~/keys`
181-
directory from source control and make sure keys are not included in your builds. Note that if you are using our
182-
Entity Framework based implementation of the operational data stores, then the keys will instead be stored in the
183-
database.
184-
3. Data protection creates keys isolated by application name. If you don't specify a name, the content root path of the
185-
application will be used. But, beginning in .NET 6.0 Microsoft changed how they handle the path, which can cause data
186-
protection keys to break. Their docs on the problem
187-
are [here](https://learn.microsoft.com/en-us/aspnet/core/security/data-protection/configuration/overview#setapplicationname),
188-
including a work-around where you de-normalize the path. Then, in .NET 7.0, this change was reverted. The solution is
189-
always to specify an explicit application name, and if you have old keys that were generated without an explicit
190-
application name, you need to set your application name to match the default behavior that produced the keys you want
191-
to be able to read.
192-
4. If your IdentityServer is hosted by IIS, special configuration is needed for data protection. In most default
193-
deployments, IIS lacks the permissions required to persist data protection keys, and falls back to using an ephemeral
194-
key generated every time the site starts up. Microsoft's docs on this issue
195-
are [here](https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/iis/advanced?view=aspnetcore-7.0#data-protection).
196100

197101
### Identity Server's Usage of Data Protection
198102

199103
Duende IdentityServer's features that rely on data protection include
200104

201-
* protecting signing keys at rest (
202-
if [automatic key management](/identityserver/fundamentals/key-management.md#automatic-key-management) is used and enabled)
105+
* protecting signing keys at rest (if [automatic key management](/identityserver/fundamentals/key-management.md#automatic-key-management) is used and enabled)
203106
* protecting [persisted grants](/identityserver/data/operational.md#persisted-grant-service) at rest (if enabled)
204107
* protecting [server-side session](/identityserver/ui/server-side-sessions/index.md) data at rest (if enabled)
205108
* protecting [the state parameter](/identityserver/ui/login/external.md#state-url-length-and-isecuredataformat) for
206109
external OIDC providers (if enabled)
207-
* protecting message payloads sent between pages in the UI (
208-
e.g. [logout context](/identityserver/ui/logout/logout-context.md) and [error context](/identityserver/ui/error.md)).
110+
* protecting message payloads sent between pages in the UI (e.g. [logout context](/identityserver/ui/logout/logout-context.md) and [error context](/identityserver/ui/error.md)).
209111
* session management (because the ASP.NET Core cookie authentication handler requires it)
210112

211113
## IdentityServer Data Stores

0 commit comments

Comments
 (0)