CodamAIDocs
Topicdone

Two origins of attributes

Platform attributes (e.g. tenant) and project attributes from the model. The difference and why it matters.

Variants
platform attributeproject attribute

What this is about

A user attribute is a named piece of information about a person that ends up in the token as a claim. A claim is an entry in the token, such as "projects": ["alpha", "beta"]. CIAS reads it on every request and puts it into the RequestContext. CDMS can use it to filter rows, see Attribute filter.

No attribute simply appears. Each one is declared by a module: the module states which information it needs about a person. There are two sources:

Not to be confused with the CIAS attributes on the user record. Those are business notes that never end up in the token, see Maintain a person’s attributes.

The picture

flowchart LR
    subgraph P["Platform"]
      CI["CIAS declares:<br/>tenant<br/>allowedTenants<br/>locale"]
    end
    subgraph M["Your project"]
      MO["Model with accessByAttribute<br/>on the field region"] --> GEN["Generator"]
      GEN --> CD["CDMS declares:<br/>region"]
    end
    CI --> K["Attribute catalog in CIAS"]
    CD --> K
    K --> KC["User profile in Keycloak<br/>and claim mapper"]
    KC --> T["Token"]

Both sources travel the same path: declaration, catalog, Keycloak, token. How that works in detail is described in Registering attributes and The path into the token.

The platform attributes

CIAS declares exactly three attributes:

AttributeKindWhat forWho changes it
tenantone value, optionalthe static tenant of a person, see Static and dynamic tenantsadministrators only
allowedTenantslist, optionalfurther tenants the person may switch toadministrators only
localeone value, default dethe language the person is addressed inthe person themselves, also on Keycloak’s account page

The names of tenant and allowedTenants can be changed with codamai.cias.token.claims.tenant-attribute and codamai.cias.token.claims.allowed-tenants-attribute. CIAS then declares them under the new name and also reads them from the token under that name. locale is always called that: Keycloak stores the language under this name anyway. You set its default value with codamai.cias.locale.default.

Why may the person not change tenant themselves, but locale they may? tenant is a statement by the installation about the person. If they could change it, they would put themselves into another customer’s data. locale is a preference that belongs to the person. If only administrators could change it, Keycloak’s own language switcher would answer with an error.

The project attributes

A project attribute comes from the model. If a model has accessByAttribute, it connects a data field with an attribute of the person, for example the field region with the attribute region. The generator collects all these attributes across all models, each one only once, and declares them for CDMS.

Every attribute generated this way is:

  • multivalued: the person can have several values, such as nord and west. The filter turns them into an IN.
  • optional, without a default value. If a person has no value, CDMS refuses their request to a filtered model, see Attribute filter.
  • bound to the person: one value per person, the same in every tenant.

If your project has no model with accessByAttribute, CDMS declares no attribute at all.

A module that writes its declaration by hand can say more: a required attribute with a default value, a preference the person changes themselves, or a value per tenant. See Registering attributes and One value per person or per tenant.

The difference at a glance

Platform attribute
from CIAS
  • steers tenant, tenant switch, language
  • always there where CIAS runs
  • name partly configurable
  • tenant and allowedTenants administrators only
Project attribute
from the model
  • cuts data down (attribute filter)
  • only if a model uses accessByAttribute
  • name from the model
  • multivalued, optional, bound to the person

Why the difference matters

Which attribute is this?
Who declares it?What is it read for?Consequence
CIAStenant, switch, languageplatform attribute. A wrong value leads the person into the wrong tenant or locks them out
CDMS, from the modelattribute filterproject attribute. A wrong value shows wrong rows, without an error
nobody–not a declared attribute. It does not reliably reach the token, and nobody may write it per tenant through CIAS

So both kinds are permissions, not mere data. Whoever may write a value decides what the person can see or reach. See Who may write an attribute.

Pitfalls

Next

Sources in the code and the knowledge base
  • commons – IdentityRegistryInterface.attributes(), models.Attribute (optional, required, preference, asMultivalued, perTenant), models.AttributeBinding
  • CIAS/cias-authorization – CiasIdentityRegistry (tenant, allowedTenants, locale), CiasAuthorizationConfiguration (codamai.cias.token.claims.tenant-attribute, allowed-tenants-attribute, codamai.cias.locale.default)
  • CDMS/cdms-generator – RoleRegistryProcessor (getAllAttributesFromContexts, writeRoleRegistry: Attribute.optional(…).asMultivalued())
  • CIAS/cias-authorization – RoleReconciliationService (attributeContradictions)
  • CIAS/cias-authorization/docs/adr – ADR-025, ADR-026, ADR-040; CIAS/cias-authentication/docs/adr – ADR-042
Search