# Identity and access management
So you want to run the login and have Iteras decide what each logged-in user has access to, typically whether the person may read the article they just opened. This page covers how to build that. It assumes the machinery described in synchronizing with an external system is set up with a webhook.
Before building, it is worth deciding whether identity should live outside Iteras at all. The Iteras self-service and paywall handle sign-in, password resets and one-time passwords out of the box, they are brandable, and they keep working as we add features - while everything on this page is something you take on building and maintaining. If it mainly exists because it was there first, consider letting Iteras handle sign-in instead. But if the external identity has to stay, this page is for you.
# What decides access
Iteras models a person as a customer with subscriptions. A subscription runs in periods, each period is on a campaign, and the period grants a set of subscription products - see concepts and terminology.
Build your access rules on the subscription products, not on
campaigns. Campaigns are commercial packaging - prices and offers
that come and go - while the products are the durable layer, and
they carry an external_id you control.
Ask for subscriptions with their current period, and you get the products:
GET /api/customers/?id=141280&fields=data,subscriptions,subscriptions.current_period
{
"customers": [
{
"id": "141280",
"data": { "name": "Jane Doe", "email": "jane@example.com" },
"subscriptions": [
{
"id": "7612471",
"state": "active",
"current_period": {
"id": "835270",
"campaign_id": "12MPRO",
"begin": "2026-06-28",
"end": "2027-06-28",
"subscribed_to": [
{ "name": "Digital access", "external_id": "digital" },
{ "name": "Archive", "external_id": "archive" }
]
}
}
]
}
]
}
The entitlement calculation on your side is then: for each
subscription in state active, take the
external_id of everything in the current period's
subscribed_to, and union them. That set is what the
user has access to. Store it on your user record, and you have
a local answer to the access question.
Two other subscription states deserve a deliberate decision
rather than being lumped in with "no access":
suspended means the subscription has not been paid and
is being sanctioned; awaiting means a paid
subscription that starts on a future date, which is different
from not having one.
# Which events change access
Set the webhook up with the customer and
subscription to paywall event categories. The
paywall category is narrow, carrying the events that can change what a person has access to,
leaving out renewals and other information. The customer events keep your user
record current, and subscription:created,
subscription:updated,
subscription:changed-status and
subscription:changed-campaign cover subscriptions
appearing, changing state and changing content.
Rather than mapping each event type to a specific change,
recompute the whole entitlement set for the affected customer
whenever any of them arrives. This is simple, idempotent, and an event
you did not anticipate becomes a harmless recomputation. Turn on
prefetching with
data,subscriptions,subscriptions.current_period so
every event carries what the recomputation needs.
Note that access changes are not announced in advance: a
subscription whose period ends tonight produces its status change
when it happens. If you cache entitlements with an expiry, use
the current period's end and re-evaluate when it
passes.
# Checking access at request time
With entitlements stored locally, the check on each page view is a local lookup, and that is how it should be - an article request should usually not wait on an HTTP call to the Iteras server.
For the occasional case where you need a definitive answer
right now - a support screen, a high-value action - read
/api/customers/?id=... directly. Just keep that off
the hot path.
If parts of your site use the Iteras paywall as well, its pass cookie is signed with a key from your account settings and carries the access level and customer number - a server-side check with no API call, which fits a static or heavily cached front end.
# Single sign-on into the self-service
You can use your own login with the self-service. Once your login has established who the user is, ask the API for a short-lived pre-authentication token for the matching Iteras customer:
GET /api/customers/?id=141280&fields=data,preauth_token&preauthseconds=300
{
"customers": [
{
"id": "141280",
"data": {
"name": "Jane Doe",
"preauth_token": "Azxd123:JOIj123:JOjOIJASDF"
}
}
]
}
Then send the user on to the self-service with the token
appended as iteraspreauth:
https://app.iteras.dk/yourservice/?iteraspreauth=Azxd123%3AJOIj123%3AJOjOIJASDF
This works for a stand-alone page as well as
embedded components.
Keep preauthseconds short, a few minutes at most:
the token is a bearer credential that ends up in browser history,
and it only has to survive one redirect.
The token does not depend on the user's password, which is the point. You are not proving the user's password to Iteras, you are asserting an identity you have already verified.
If Iteras holds the passwords and you are building a login screen in front of them, use /api/authenticatecustomer/ instead, which verifies an ID or email plus password and can return a pre-auth token in the same call. Mind the note about putting a rate limit in front.
# Turning off the built-in login
When identity lives in your system, Iteras can be configured so that customers are never offered a second way to sign in. Turn on external login for customers in the customer service settings, and the self-service and paywall stop showing their own login and instead send anyone who needs to sign in to your login page. Turn on external passwords for customers in the account settings, and Iteras stops managing passwords entirely - no password on the customer, no reset flow, no password links in emails.
Beyond that, you can choose which login methods Iteras accepts if it should still handle some sign-ins, and you can point the self-service URL to the page on your own site where the self-service is embedded, so outgoing emails link there.