Skip to content

Commit 46a7953

Browse files
committed
Merge branch 'main' into ar/more-specific-isolation
2 parents 07678f6 + 7bb23f7 commit 46a7953

17 files changed

Lines changed: 593 additions & 131 deletions

File tree

README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,25 @@ redirects: {
216216
This will remove the old page from the navigation structure, but keeps the URL around
217217
with a redirect to the new location.
218218

219+
## 🤖 AI-Friendly Documentation
220+
221+
We make our docs consumable by AI agents and LLMs, not just humans.
222+
223+
### What we do
224+
225+
* **[`llms.txt`](https://docs.duendesoftware.com/llms.txt) and [`llms-full.txt`](https://docs.duendesoftware.com/llms-full.txt)** — Machine-readable site index and full content dump following the [llms.txt proposal](https://llmstxt.org/), so AI tools can discover and ingest our docs.
226+
* **Content negotiation** — The server supports `Accept: text/markdown` to return raw Markdown for any docs page, giving AI agents clean content without HTML noise.
227+
* **`robots.txt` signals** — We don't block AI crawlers. The robots.txt includes references to `llms.txt` so crawlers can find structured content.
228+
229+
Beyond this repo, Duende also provides tools that give AI coding assistants specialized knowledge (see [AI Agent Tools](https://docs.duendesoftware.com/general/ai-agent-tools/)):
230+
231+
* **[Agent Skills](https://github.com/DuendeSoftware/duende-skills)** — Structured `SKILL.md` files following the [Agent Skills format](https://agentskills.io/) that give AI assistants domain expertise on IdentityServer, BFF, token management, and more. Loaded automatically by compatible IDEs.
232+
* **[MCP Server](https://github.com/DuendeSoftware/products/blob/main/docs-mcp/README.md)** — A local [Model Context Protocol](https://modelcontextprotocol.io/) server that gives AI assistants search and fetch access to the full Duende docs, blog, and sample code via SQLite full-text search.
233+
234+
### Why
235+
236+
Developers increasingly use AI assistants to find answers. If our docs aren't AI-friendly, those assistants hallucinate or point elsewhere. Making content machine-readable means Duende products get accurate representation in AI-generated answers.
237+
219238
## ⚖️ License
220239

221240
For all licensing information, refer to the relevant license files:

astro/astro.config.mjs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import * as fs from "node:fs";
1717
import { duendeOpenGraphImage } from "./src/plugins/duende-og-image.js";
1818
import removeMarkdownExtensions from "./src/plugins/remove-markdown-extensions.js";
1919
import staticRedirects from "./src/plugins/static-redirects.js";
20+
import markdownOutput from "./src/plugins/markdown-output.js";
2021

2122
// https://astro.build/config
2223
export default defineConfig({
@@ -233,6 +234,7 @@ export default defineConfig({
233234
contentDir: "./src/content/docs",
234235
}),
235236
staticRedirects(),
237+
markdownOutput(),
236238
opengraphImages({
237239
options: {
238240
fonts: [

astro/package-lock.json

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

astro/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,13 @@
3434
"astro-opengraph-images": "^1.14.3",
3535
"astro-redirect-from": "^1.3.5",
3636
"astro-rehype-relative-markdown-links": "^0.19.0",
37+
"hast-util-to-text": "^4.0.2",
3738
"jsdom": "^29.0.2",
3839
"patch-package": "^8.0.1",
3940
"react": "^19.2.4",
4041
"rehype-external-links": "^3.0.0",
42+
"rehype-parse": "^9.0.1",
43+
"rehype-remark": "^10.0.1",
4144
"satori": "^0.26.0",
4245
"sharp": "^0.34.5",
4346
"starlight-auto-sidebar": "^0.2.0",

astro/public/robots.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
User-agent: *
2+
Content-Signal: ai-train=yes, search=yes, ai-input=yes
23
Allow: /
34

4-
Sitemap: https://docs.duendesoftware.com/sitemap-index.xml
5+
Sitemap: https://docs.duendesoftware.com/sitemap-index.xml

astro/src/content/docs/identityserver/configuration/dcr.mdx

Lines changed: 95 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,36 @@ redirect_from:
1616
- /identityserver/v7/configuration/dcr/installation/
1717
---
1818

19-
import { Steps } from "@astrojs/starlight/components";
19+
import { Code, Steps } from "@astrojs/starlight/components";
20+
21+
export const addMainPackageSnippet = `
22+
cd Configuration
23+
dotnet add package Duende.IdentityServer.Configuration
24+
`;
25+
26+
export const addStoragePackageSnippet = `dotnet add package Duende.IdentityServer.Configuration.EntityFramework`;
27+
28+
export const licenseSnippet = `
29+
builder.Services.AddIdentityServerConfiguration(opt =>
30+
opt.LicenseKey = "<license>";
31+
);
32+
`;
33+
34+
export const dbConfigurationSnippet = `
35+
builder.Services.AddIdentityServerConfiguration(opt =>
36+
opt.LicenseKey = "<license>"
37+
).AddClientConfigurationStore();` + '\r\n' + `
38+
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
39+
builder.Services.AddConfigurationDbContext<ConfigurationDbContext>(options =>
40+
{
41+
options.ConfigureDbContext = builder => builder.UseSqlite(connectionString);
42+
});
43+
`;
44+
45+
export const mapDcrEndpointSnippet = `
46+
app.MapDynamicClientRegistration()
47+
.RequireAuthorization("DCR");
48+
`;
2049

2150
Dynamic Client Registration (DCR) is the process of registering OAuth clients
2251
dynamically. It allows OAuth client applications to programmatically register
@@ -53,31 +82,24 @@ To host the Configuration API separately from IdentityServer, you will need to
5382
create a new ASP.NET Core Web application which will host the Configuration API.
5483

5584
<Steps>
85+
5686
1. **Create a new project of type "Empty Web Application"**
5787

5888
```bash title=Terminal
5989
dotnet new web -n Configuration
6090
```
6191

6292
2. **Add the `Duende.IdentityServer.Configuration` package**
63-
64-
```bash title=Terminal
65-
cd Configuration
66-
dotnet add package Duende.IdentityServer.Configuration
67-
```
68-
93+
94+
<Code code={addMainPackageSnippet} lang="bash" title="Terminal" />
95+
6996
3. **Configure services to include the Configuration API**
70-
71-
```csharp
72-
// Program.cs
73-
builder.Services.AddIdentityServerConfiguration(opt =>
74-
opt.LicenseKey = "<license>";
75-
);
76-
```
97+
98+
<Code code={licenseSnippet} lang="csharp" title="Program.cs" />
7799

78100
:::note
79101
This feature is part of the [Duende IdentityServer Business and Enterprise Edition](https://duendesoftware.com/products/identityserver).
80-
Configure the same license key for IdentityServer and the Configuration API.
102+
You don't need to acquire an additional license, use the same license key for Duende IdentityServer and the DCR Configuration API.
81103
:::
82104

83105
4. **Add and configure the client configuration store**
@@ -90,43 +112,27 @@ create a new ASP.NET Core Web application which will host the Configuration API.
90112
the interface yourself. See [the IClientConfigurationStore reference](/identityserver/reference/stores/index.md)
91113
for more details. If you wish to use the built-in implementation, install its NuGet
92114
package and add it to the ASP.NET Core service provider.
93-
94-
```bash title=Terminal
95-
dotnet add package Duende.IdentityServer.Configuration.EntityFramework
96-
```
115+
116+
<Code code={addStoragePackageSnippet} lang="bash" title="Terminal" />
97117

98118
The `AddClientConfigurationStore()` extension method registers the built-in
99119
implementation of the `IClientConfigurationStore` interface with the service
100120
provider. Make sure to also configure the connection string to the
101121
[configuration store](/identityserver/data/ef.md#configuration-store-support):
102122

103-
```csharp {4}
104-
// Program.cs
105-
builder.Services.AddIdentityServerConfiguration(opt =>
106-
opt.LicenseKey = "<license>"
107-
).AddClientConfigurationStore();
108-
109-
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
110-
builder.Services.AddConfigurationDbContext<ConfigurationDbContext>(options =>
111-
{
112-
options.ConfigureDbContext = builder => builder.UseSqlite(connectionString);
113-
});
114-
```
115-
123+
<Code code={dbConfigurationSnippet} lang="csharp" title="Program.cs" mark={[3]} />
124+
116125
5. **Map the Configuration API endpoints**
117-
118-
```csharp
119-
// Program.cs
120-
app.MapDynamicClientRegistration()
121-
.RequireAuthorization("DCR");
122-
```
123-
126+
127+
<Code code={mapDcrEndpointSnippet} lang="csharp" title="Program.cs" />
128+
124129
The `MapDynamicClientRegistration` extension method registers the DCR endpoints
125130
and returns an `IEndpointConventionBuilder` which you can use to define authorization
126131
requirements for your DCR endpoint.
127132

128133
See [Authorization](#authorization) for more details about implementing authorization for
129134
the DCR endpoint.
135+
130136
</Steps>
131137

132138
### Shared Host For Configuration API and IdentityServer
@@ -136,26 +142,18 @@ You'll need to add the Configuration API's services to the service collection,
136142
and configure the store implementation.
137143

138144
<Steps>
145+
139146
1. **Add the `Duende.IdentityServer.Configuration` package**
140147

141-
```bash title=Terminal
142-
cd Configuration
143-
dotnet add package Duende.IdentityServer.Configuration
144-
```
148+
<Code code={addMainPackageSnippet} lang="bash" title="Terminal" />
145149

146150
2. **Configure services to include the Configuration API**
147151

148-
```csharp
149-
// Program.cs
150-
builder.Services.AddIdentityServerConfiguration(opt =>
151-
opt.LicenseKey = "<license>";
152-
);
153-
```
152+
<Code code={licenseSnippet} lang="csharp" title="Program.cs" />
154153

155154
:::note
156-
The Configuration API feature is included in the Duende IdentityServer Business
157-
edition license and higher. Use the same license key for IdentityServer and the
158-
Configuration API.
155+
This feature is part of the [Duende IdentityServer Business and Enterprise Edition](https://duendesoftware.com/products/identityserver).
156+
You don't need to acquire an additional license, use the same license key for Duende IdentityServer and the DCR Configuration API.
159157
:::
160158

161159
3. **Add and configure the client configuration store**
@@ -169,45 +167,69 @@ and configure the store implementation.
169167
for more details. If you wish to use the built-in implementation, install its NuGet
170168
package and add it to the ASP.NET Core service provider.
171169

172-
```bash title=Terminal
173-
dotnet add package Duende.IdentityServer.Configuration.EntityFramework
174-
```
170+
<Code code={addStoragePackageSnippet} lang="bash" title="Terminal" />
175171

176172
The `AddClientConfigurationStore()` extension method registers the built-in
177173
implementation of the `IClientConfigurationStore` interface with the service
178174
provider. Make sure to also configure the connection string to the
179175
[configuration store](/identityserver/data/ef.md#configuration-store-support) if
180176
you haven't already as part of your IdentityServer host:
181177

182-
```csharp {4}
183-
// Program.cs
184-
builder.Services.AddIdentityServerConfiguration(opt =>
185-
opt.LicenseKey = "<license>"
186-
).AddClientConfigurationStore();
187-
188-
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
189-
builder.Services.AddConfigurationDbContext<ConfigurationDbContext>(options =>
190-
{
191-
options.ConfigureDbContext = builder => builder.UseSqlite(connectionString);
192-
});
193-
```
178+
<Code code={dbConfigurationSnippet} lang="csharp" title="Program.cs" mark={[3]} />
194179

195180
4. **Map the Configuration API endpoints**
196181

197-
```csharp
198-
// Program.cs
199-
app.MapDynamicClientRegistration()
200-
.RequireAuthorization("DCR");
201-
```
182+
<Code code={mapDcrEndpointSnippet} lang="csharp" title="Program.cs" />
202183

203184
The `MapDynamicClientRegistration` extension method registers the DCR endpoints
204185
and returns an `IEndpointConventionBuilder` which you can use to define authorization
205186
requirements for your DCR endpoint.
206187

207188
See [Authorization](#authorization) for more details about implementing authorization for
208189
the DCR endpoint.
190+
209191
</Steps>
210192

193+
### Adding the Registration Endpoint to the Discovery Document
194+
195+
By default, the Dynamic Client Registration (DCR) endpoint is not included in the [discovery document](/identityserver/reference/endpoints/discovery.md) of Duende IdentityServer.
196+
197+
To include it, change the Discovery Document options when registering IdentityServer in the service collection:
198+
199+
```csharp
200+
// Program.cs
201+
builder.Services.AddIdentityServer(options =>
202+
{
203+
// Either use a static URL for the registration endpoint, when hosted outside of IdentityServer:
204+
options.Discovery.DynamicClientRegistration.RegistrationEndpointMode =
205+
RegistrationEndpointMode.Static;
206+
207+
options.Discovery.DynamicClientRegistration.StaticRegistrationEndpoint =
208+
new Uri("https://my-configuration-api/connect/dcr");
209+
210+
// Or use inferred when the registration endpoint is hosted within IdentityServer:
211+
options.Discovery.DynamicClientRegistration.RegistrationEndpointMode =
212+
RegistrationEndpointMode.Inferred;
213+
});
214+
```
215+
216+
:::note
217+
DCR support was added to Duende IdentityServer v7.4. If you cannot upgrade your IdentityServer solution yet,
218+
you'll have to add custom entries to the Discovery Document instead:
219+
220+
```csharp
221+
// Program.cs
222+
using Duende.IdentityModel;
223+
224+
builder.Services.AddIdentityServer(options =>
225+
{
226+
options.Discovery.CustomEntries.Add
227+
OidcConstants.Discovery.RegistrationEndpoint,
228+
"https://my-configuration-api/connect/dcr");
229+
});
230+
```
231+
:::
232+
211233
## Authorization
212234

213235
When implementing Dynamic Client Registration (DCR), it is important to consider
@@ -339,4 +361,4 @@ For more details, see the [reference section on DCR request processing](/identit
339361
To customize the HTTP responses of the Configuration API, you can implement the `IDynamicClientRegistrationResponseGenerator`
340362
interface, or extend the default `DynamicClientRegistrationResponseGenerator`.
341363

342-
For more details, see the [reference section on rDCR esponse generation](/identityserver/reference/dcr/response.md).
364+
For more details, see the [reference section on DCR response generation](/identityserver/reference/dcr/response.md).

astro/src/content/docs/identityserver/overview/big-picture.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ depending on your needs)
7878
and add the IdentityServer middleware to that application. The middleware adds the necessary protocol heads to the
7979
application so that clients can talk to it using those standard protocols.
8080

81-
![IdentityServer middleware diagram and its relatinship in the ASP.NET Core pipeline](images/middleware.svg)
81+
![IdentityServer middleware diagram and its relationship in the ASP.NET Core pipeline](images/middleware.svg)
8282

8383
The hosting application can be as complex as you want, but we typically recommend to keep the attack surface as small as
8484
possible by including

astro/src/content/docs/identityserver/quickstarts/javascript-clients/js-with-backend.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ Add the following to `src/JavaScriptClient/Program.cs`:
125125
options.SaveTokens = true;
126126
options.GetClaimsFromUserInfoEndpoint = true;
127127
options.MapInboundClaims = false;
128-
}
128+
})
129129
.ConfigureCookies(options => options.Cookie.SameSite = SameSiteMode.Strict)
130130
.AddRemoteApis();
131131

astro/src/data/banner.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
"content": "<strong>New Livestream:</strong> A First Look at Duende's First-Party SAML 2.0 Support. <a href=\"https://duendesoftware.com/webinars/first-look-at-duende-first-party-saml-2-0-support\">Register Now!</a>"
2+
"content": ""
33
}

0 commit comments

Comments
 (0)