# Reference Architecture: Member Portal and Intranet

> Source: https://agilitycms.com/docs/developers/reference-architecture-member-portal

Use this architecture when some of your content is only for signed-in people: a customer or partner portal, a members' area, or an employee intranet. Agility manages the content and who can edit it. Your front end decides who can read it.

The central fact: **Agility controls access to the CMS, not to your site.** Roles, teams and SSO govern your editors. Your visitors sign in to your front end, through an identity provider you choose, and your server decides what each visitor sees.

## Components

| Component | Owned by | Role |
| --- | --- | --- |
| Identity provider | You (for example Microsoft Entra ID, Auth0 or Okta) | Signs visitors in and tells your app who they are and which groups they belong to |
| Agility instance | Agility (you configure it) | Pages and content, with fields that say who each item is for |
| Front-end server | You | Checks the session, reads content from Agility on the server, filters it by audience |
| Secure file storage (optional) | You, through an Agility app | Confidential documents served by short-lived signed URLs |
| Search index (optional) | You | Built from Agility content, filtered by audience at query time |

[Auth](/docs/developers/auth0) walks through adding Auth0 to a Next.js site that reads from Agility.

## Modeling audiences

Decide what "who can see this" means in your organization, then model it as content:

- **An audience field on content and pages.** For example a linked list of audiences (Members, Partners, Staff, a department) that editors pick from. Keep the list in Agility so editors manage it, and map each audience to a group in your identity provider.
- **A members-only area of the sitemap.** For example everything under `/members`. Your server requires a session for that path. This is simple, but it protects pages, not the content items they show.
- **A separate instance for confidential content.** Content that must not be readable with your public site's API key goes in its own instance, with its own keys and its own editors. See [Choose Your Tenancy Model](/docs/developers/choose-your-tenancy-model).

## Data flow

| Step | From | To | What happens |
| --- | --- | --- | --- |
| 1 | Browser | Identity provider | The visitor signs in |
| 2 | Browser | Your server | Requests a page with a session cookie |
| 3 | Your server | Its session | Reads the visitor's audiences or groups |
| 4 | Your server | Content Fetch API (through your cache) | Reads the page and content with the fetch key, on the server only |
| 5 | Your server | Browser | Returns only what the visitor's audiences allow |
| 6 | Browser | Secure file storage | Downloads confidential files through signed, expiring URLs |

## What is public by design

Plan around these facts:

- **A fetch key reads all published content in its instance.** The Content Fetch API isn't secured by sitemap ([Using Agility for Multiple Sites](/docs/overview/using-agility-cms-for-multiple-sites)), page or audience. So never call the Fetch API from the browser for gated content, never ship the key to the browser, and filter on the server.
- **Hiding a page from menus doesn't protect it.** Your server must check the session for every gated route, including dynamic pages.
- **Media library assets are served from a public CDN URL.** Anyone with an asset's `cdn.aglty.io` URL can download it, without a key. Don't upload confidential files to the media library. Use a secure files app instead: [Secure Files - Azure](/docs/apps/secure-files-azure) or [Secure Files - AWS](/docs/apps/secure-files-aws). They keep files in your own Azure Blob Storage or AWS S3 storage, and your server hands out pre-signed URLs that expire. For other options for private files, contact Agility support.
- **Copies of content need the same filter.** Webhook payloads tell you what changed, not the content itself ([Webhook Events and Payload Reference](/docs/developers/webhook-events-and-payloads)). Anything you copy into a search index or another system must be filtered by audience there too.

## Caching

| What | Where it may be cached | Rule |
| --- | --- | --- |
| Content read from Agility | Your server's data cache | Cache it the same way as on a public site. Filtering happens after the read |
| Pages rendered per audience | Your server, keyed by audience | Fine when the key includes the audience, never the individual |
| Pages rendered per person | Nowhere shared | Send [`Cache-Control: private`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Cache-Control) so no shared cache, such as a CDN, stores them |
| Public pages | Your CDN | As on a [marketing site](/docs/developers/reference-architecture-marketing-site) |

A shared CDN that caches a signed-in page can serve it to the next visitor. Check the response headers of every gated route.

## Preview

Editors previewing gated pages need to see them as a given audience. Give your preview deployment a way to choose the audience, for example a switcher shown only in preview mode, rather than signing editors in as members. When an editor previews, Agility opens your site with `agilitypreviewkey` in the query string, and your server reads content with the preview key. See [Setting Up Preview](/docs/developers/setting-up-preview).

## For an intranet

- **Editors and staff can use the same identity provider.** Agility supports SSO for its own users (see [Hosting, Security & Compliance](/docs/owners-admins/hosting-security-and-compliance)), and your intranet front end can use the same identity provider for readers. They are still two separate sign-ins: one to the CMS, one to your intranet.
- **Microsoft 365 Copilot.** Staff with Agility accounts can connect Copilot to Agility through the MCP server. Agility permissions apply per user, so Copilot can do only what the signed-in user is allowed to do. It is a tool for people who work in Agility, not a way to deliver content to intranet readers. See [Connect the Agility MCP Server to Microsoft 365 Copilot](/docs/developers/connect-agility-mcp-server-to-microsoft-365-copilot).

## Failure modes

| What goes wrong | Effect | Design for it |
| --- | --- | --- |
| Gated content fetched in the browser | Anyone can read it with the key from your page | Fetch on the server only |
| A signed-in page cached by a shared CDN | One person's page shown to others | `Cache-Control: private` on gated responses, and test it |
| A confidential PDF uploaded to the media library | Public download for anyone with the link | Secure files app with signed URLs |
| A gated route forgotten in the session check | Content readable without signing in | Protect by path prefix and by content audience, and test both |
| The identity provider is down | Nobody can sign in | Public pages keep working. Show a clear message on gated routes |
| An audience removed in the identity provider but not in Agility | Content shown to nobody, or to the wrong group | Keep the audience list in one place and review it |

## Related

- [Reference Architectures](/docs/developers/reference-architectures)
- [Choose Your Tenancy Model](/docs/developers/choose-your-tenancy-model)
- [Auth](/docs/developers/auth0)
- [Roles and Permissions Matrix](/docs/owners-admins/roles-and-permissions-matrix)
- [Hosting, Security & Compliance](/docs/owners-admins/hosting-security-and-compliance)

---

## Related pages

- [Reference Architectures](https://agilitycms.com/docs/developers/reference-architectures.md)
- [Reference Architecture: Marketing Website](https://agilitycms.com/docs/developers/reference-architecture-marketing-site.md)
- [Reference Architecture: Multi-Brand and Multi-Site](https://agilitycms.com/docs/developers/reference-architecture-multi-brand.md)
- [Reference Architecture: Headless Commerce](https://agilitycms.com/docs/developers/reference-architecture-headless-commerce.md)
- [Reference Architecture: Multi-Channel Delivery](https://agilitycms.com/docs/developers/reference-architecture-multi-channel.md)
- [Choose Your Tenancy Model](https://agilitycms.com/docs/developers/choose-your-tenancy-model.md)
- [Handle Rate Limits and Outages Gracefully](https://agilitycms.com/docs/developers/handle-rate-limits-and-outages.md)
- [Content Security Policy and Network Allowlist](https://agilitycms.com/docs/developers/content-security-policy-and-network-allowlist.md)

Index of every docs page: https://agilitycms.com/docs/llms.txt
