Portal access boundaries
A portal lets chosen people and groups use chosen agents from a page of their own. Creating and configuring portals is covered in Administering portals. This page covers the access side: how the policy engine decides who may open a portal and run its agents, how to restrict a portal to your networks, how an administrator tries a portal as a test, how View as previews what a person or group would meet, and how people who arrive through an embed are admitted.
Enterprise feature
Portals are part of the Enterprise edition. The rules and policies described here are accepted only on an installation that has portals: without them there is nothing to apply a rule to, and a deny about portals is refused like any rule that cannot match a request.
Requires a Console release with the IAM engine
The built-in managed:portal:* policies, the network restriction, test sessions and View as exist in releases that include the IAM engine and a portals-enabled Enterprise build.
What the engine decides
Three questions are asked about a portal, in the portal channel, and one in the dashboard and the API:
| Action | Asked when | Level |
|---|---|---|
portal.use | A person opens the portal, on every request they make to it. | Read |
agent.invoke | A person sends a message to one of the portal's agents. | Write |
agent.approve | A person answers a pending approval or question of a session started through the portal. | Write |
portal.conversations_view | An administrator opens the Conversations tab or one conversation of the portal (dashboard and api channels). | Admin |
portal.conversations_view is held by workspace owners and admins; a deny rule can take it away, and an allow rule cannot lift an ordinary member over the Admin level. See Conversations.
The access list is the portal's built-in policy
The access list lives on the portal (Portals → the portal → Access: everyone in the workspace, or selected people and groups). The built-in managed:portal:* policies read it, so editing the list never touches a policy and nothing is stored per portal. A change to the list applies on the next request.
Opening a portal is allowed only by the list: a workspace role, a service permission or an allow rule cannot open a portal the list does not name, and the workspace owner is no exception. API tokens never open portals. The exceptions are a workspace owner or admin in a marked test session and, for a portal that takes every verified embedded person, someone who arrived through its embed.
Custom deny rules still apply on top
Use a deny rule to block a person or group that is on the list, to freeze a portal, or to stop one agent from running in portals:
{
"effect": "forbid",
"principals": { "groups": ["6b1f0c52-2f0a-4c1e-9c61-3f0d8a1b7e11"] },
"actions": ["portal.use"],
"resources": { "resources": [{ "type": "portal", "id": "<portal id>" }] },
"conditions": { "channels": ["portal"] }
}Readin theportalchannel covers opening portals andWritecovers running their agents and answering their requests. A rule such as "contractors: deny Write everywhere" therefore also stops them from sending messages in a portal while they can still open it.- A rule that names a portal also covers the agents run through it (an agent run through a portal is in that portal).
- An allow rule never adds anyone to a portal; the editor says so when you write one.
Network restriction
A portal can list the networks it may be used from, so it works from your corporate network and nowhere else. The click-path is also described in Administering portals; this section adds how the engine treats the list.
Set it up
- Open Portals → the portal → Access.
- Under Network restriction, set Allowed networks to Only these networks.
- Under IP ranges, enter one range per line: a CIDR such as
203.0.113.0/24, a single address, or an IPv6 range (2001:db8::/32). - Optionally write a Message for people outside these networks (up to 300 characters). It is shown with the reference code on the refusal page; leave it empty for the default.
- Use Check your own address to see whether you would be let in before you save. It shows the address as the console sees it and a verdict (You would be let in: 203.0.113.0/24 lists your address or You would be refused). Check another address tests any other address against the draft list.
- Save.
How it behaves
| What is checked | The address the console sees for the request. It covers people using the embedded chat and administrators trying the portal as well. |
| What is refused | Opening the portal, running its agents and answering its approvals, from every address outside the list. |
| Overrides | None. The network restriction applies to test sessions and to embedded people too. |
| Unreadable address | A request whose address cannot be read is refused when a list is set. |
| Empty list | Not accepted: an empty list would lock everybody out. |
| Size | At most 32 ranges per portal (IPv4 or IPv6, a single address or a CIDR; IPv4 addresses written inside IPv6 are not accepted). Combine neighbouring ranges into larger ones when you need more. |
| Portals without a list | Not affected. "Any network" is the default. |
Set TRUSTED_PROXIES behind a proxy
The address is the one described under Client address and TRUSTED_PROXIES. Without TRUSTED_PROXIES, behind a reverse proxy every caller looks like the proxy: you would either refuse everybody or admit everybody who passes through the proxy. Set it before you rely on this.
The Access check and the API
The Access check reads the same list: give it context.ip and it says whether the address is let in, and which built-in rule refused it. The result lists the portal's network setting as a mode and a count; the ranges themselves are never published by the check.
Saving a bad list through the admin API answers 400 with code: "invalid_networks" and issues such as invalid_cidr (with the offending entry), too_many and empty_allow_list.
Test sessions
A workspace owner or admin can open a portal as a test without being on its access list: Open as test on the portal's page. Use it to see what people would meet, including the network restriction. The portal admin guide has the click-path (Test sessions and View as).
- The portal marks the session and shows a banner (Test session. Nothing here is counted in the statistics.) with Leave test.
- Only owners and admins. The built-in rules honour the mark for those two roles only; a member who sends it gains nothing. The mark is a signed cookie bound to the person, the workspace and one portal, it expires after four hours, and the engine re-checks the person's role on every request, so the cookie of somebody who is no longer an admin opens nothing.
- Left out of the statistics. Conversations of a test session are flagged and not counted.
- Audited. Each use is written to the audit log as the event
portal.test_session(filed under the portals service), at most once a minute per person and portal. - The network restriction still applies. A test shows what people would meet.
The built-in policies behind it are managed:portal:test-use and managed:portal:test-agent.
View as
View as answers, without running anything, what a person or a group would meet at a portal. It asks the same engine, with the same built-in rules and custom policies, that the portal runtime asks. Nothing is recorded, nobody is impersonated: there is no session, conversation or token behind a view, only decisions.
- Open the portal and use View as.
- Choose the Audience: a Person, or a Group (a group is checked as a plain member of it, with no other group).
- Optionally enter From this address to test a network restriction, or tick Arriving through the embedded chat.
- Select Show what they would see.
The result says whether they can open the portal, and for each agent the portal offers whether they can use it, with the rule that decides. A disabled portal, or a disabled account, is called out. At most 50 agents are decided; the result says when the portal offers more.
The Access check accepts a group as the principal for portal.use, agent.invoke and agent.approve in the portal channel for the same purpose.
People who arrive through an embed
A portal can be embedded in another application, which tells the portal who the person is with a signed token (set-up and token minting are described in Embedding a portal and Sign people in: the identity token). The access list decides by default (access.embedded: access_list); a portal can instead take every person its token check verified (any_verified). The portal marks such requests (context.embedded), and only the portal runtime can set the mark. The network restriction applies to both.
The token is checked and the person it names is found by the same two pieces that serve Acting for a user: the statement is verified like any identity assertion (the pinned algorithm, the issuer, an audience derived from the portal such as cognipeer-portal:<the portal's key>, a short life, and a jti that is accepted once, which a portal requires and the API call does not), and the person is found by the same rules as in Finding the person. Everything said about external users and groups that follow the statement holds for a portal's embed as well. A portal has its own mapping, but the groups a group map fills belong to the issuer: two portals (or an API token) that trust the same issuer fill the same groups.
What is specific to a portal:
- A statement never signs in as a workspace owner, nor as an administrator (by their own role or through a group that grants one), whatever the mapping says. A refused account is left exactly as it was. A portal has no Allow administrators switch: owners and admins try the portal with a test session.
- The session that follows belongs to that portal and to the page that embedded it.
- The mapping can also trust the host's addresses (
trustEmails): treat the statement's email as verified even withoutemail_verified: true. Turn it on only for an issuer that never signs an address it did not check.
Refusals show a reference code
When somebody is refused at a portal, the person sees a reference code on the portal's error page (and in the message of a refused chat message). An administrator pastes it into IAM center → Access check → Look up a denied request and sees the action on the portal or agent, the channel, the people and rules that decided and, for a rule that has since been switched off or deleted, which one and what the current policies say about the same request.
Like every refusal, it is written to the audit log, once per person, action, portal and reason per minute: a client that keeps retrying shares one reference code and one row.
When the engine cannot decide, the portal fails closed: the person is told to try again, with a reference code, and the refusal is counted like any other "authorization unavailable" (503). It never falls back to another rule.
Large access lists
The engine's cost grows with the number of people and groups on a list (about 7 microseconds each). Above 200 entries it evaluates only the requester's part of the list, which gives the same answer. A custom rule written in Cedar that looks at other members of resource.allowedUsers sees that part, not the whole list.
Troubleshooting
A person on the access list cannot open the portal. In order: is the portal enabled? Is the account disabled? Does a deny rule name them or the portal? Is the portal's network restriction on, and is their address listed? Paste the reference code from the error page into the Access check, or use View as for the person with their address.
Everybody is refused after I turned on the network restriction. Check TRUSTED_PROXIES: behind a proxy every caller may look like the proxy, and a request whose address cannot be read is refused.
An administrator cannot open the portal as a test. The network restriction still applies to test sessions. Add the administrator's address, or test from an address on the list. The self-test in the form tells you whether your address is let in.
My allow rule did not add anybody to the portal. By design: only the access list admits people. Edit the list on the portal.
An embedded person is refused with "Your account is not set up for this chat". Nobody matched the statement and the portal's provisioning is set to refuse unknown people. Choose what happens to a person nobody matches in the portal's embed settings, or create the account first.
What's new
- Network restriction per portal, with a self-test and a custom refusal message.
- Test sessions for owners and admins, audited and left out of the statistics.
- View as for a person or a group, with an optional address and embed flag.
- People who arrive through an embed are admitted through the platform's shared verified-identity rules.

