Files
zitadel/apps/docs
c9d747d407 fix(api): prevent cross-instance caching of well-known app link files (#12644)
# Which Problems Are Solved

The `/.well-known/apple-app-site-association` and
`/.well-known/assetlinks.json` responses are instance specific: the body
depends on the requested host. The responses did not declare this, so a
shared cache whose cache key does not include the host could store one
instance's file and serve it on another instance's domain. This could
result in a wrong or empty file being returned intermittently, breaking
native passkey verification.

Dropping the `public` directive (#12634) was not sufficient: depending
on its cache mode, a shared cache may store any response carrying a
`max-age`.

The docs page for native app links also still documented the old
`Cache-Control: public` header and only the single `get_login_creds`
relation (missing `handle_all_urls`, added in #12634).

# How the Problems Are Solved

- Send **`Vary: Host`** on both well-known responses, declaring that the
body depends on the host: a spec-compliant shared cache must store
per-host variants or skip caching. Clients addressing a single host (the
Apple and Google verifiers, browsers) are unaffected and keep honoring
the configured `max-age`.
- Correct the outdated caching reasoning in the code comments.
- Guard the header with unit and integration tests.
- Update the native app links docs page: both Digital Asset Links
relations and the current response headers.

# Additional Changes

None. `WellKnown.AppLinksCacheControlMaxAge` behavior is unchanged (`0`
still results in `no-store`).

# Additional Context

- Follow-up to #12634; relates to #12497.
- Verified with interleaved requests against two instances: responses
are no longer reused across domains, and each domain consistently serves
its own configuration.
- To be cherry-picked to `v4.x` from `main` once merged.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Fable 5 <[email protected]>
2026-08-26 10:57:28 +02:00
..
2026-01-30 18:11:12 +00:00

@zitadel/docs

Documentation for Zitadel, built with Fumadocs and Next.js.

Getting Started

Ensure you have followed the root quick start to set up dependencies.

Local Development

Ensure all dependencies are installed:

pnpm install

Start the development server:

pnpm nx run @zitadel/docs:dev

The site will be available at http://localhost:3000.

Scripts

Key scripts for documentation workflows:

Script Description
dev Starts the development server.
build Builds the production application.
fetch:remote-content Fetches remote tags and referenced content.
generate Runs all generation steps (fetch:remote-content, generate:proto-docs, generate:api-reference, generate:index-pages).
check:links Validates content integrity (broken links, missing frontmatter, schema errors).
check-types Validates typescript types.
test Runs all validation steps (check-types, check:links).
lint checks for code style and syntax errors (ESLint).
clean Cleans the build output and generated files.

Validation

  • Code Quality: Run pnpm nx run @zitadel/docs:lint to check for syntax and style issues in JS/TS/MDX files.
  • Content Integrity: Run pnpm nx run @zitadel/docs:check-links to validate content structure, including:
    • Broken internal links
    • Missing required front-matter (e.g., title)
    • Image references

Troubleshooting

Issue: Nx configuration not found or "nx" command not found

If you see errors like:

 NX   Cannot find configuration for task @zitadel/zitadel:@zitadel/docs:generate

Pass --verbose to see the stacktrace.

or

pnpm nx run @zitadel/docs:dev
 ERR_PNPM_RECURSIVE_EXEC_FIRST_FAIL  Command "nx" not found

Did you mean "pnpm nx"?

Root cause: Your dependency cache or node_modules is out of sync.

Solution: Run these commands from the repository root in order:

  1. Clear node_modules: rm -rf node_modules — removes the installed dependency folder
  2. Clear pnpm cache: pnpm cache delete — clears pnpm's internal package cache
  3. Reinstall dependencies: pnpm install — reinstalls all dependencies fresh
  4. Test the setup: pnpm nx run @zitadel/docs:generate — verifies everything works

This resolves 99% of setup-related issues.

Contributing

Build Process

The docs build process automatically handles the following steps via generate:

  1. Downloads required protoc plugins.
  2. Generates gRPC documentation from proto files.
  3. Generates API documentation from OpenAPI specs.
  4. Generates index files for directory structures.

Style Guide

  • Variables: Use environment variables in code snippets where possible.
  • Embedded Content: Use _filename.mdx for content embedded in other pages (not indexed individually).
  • Code Embedding: Use the file property in code blocks to embed code from the repo.
  • Voice: Use active voice and sentence case for titles.

Refer to the Google Developer Style Guide for general guidelines.

Adding Content

All documentation content is located in the content directory. Note that the system strictly accepts only .mdx files.

To add a new page:

  1. Create a .mdx file in the appropriate subdirectory of content.
  2. Register the new page in the sidebar settings at lib/sidebar-data.ts to make it accessible in the navigation.

Pull Requests

Use docs(<scope>): <short summary> for PR titles. Pass quality checks before submitting:

pnpm nx run @zitadel/docs:build