Grant Application Access
Asks CNA Auth to give a person access to an application, provisioning the account and user when they are new. Published by cna-one when an invited user is mirrored into a person; handled by cna-auth.
Overview
Intent to grant a person access to an application. It is a command: CNA AuthCNA AuthServicev1.0.0Authentication and identity provider for the CNA platform (accounts, tokens, OTP/2FA, per-application access grants). Co...SubscribesGrantApplicationAccess, RevokeApplicationAccess +2Ownercna-platformMapRepoView docs validates it and may reject it silently.
When it is published. CNA OneCNA OneServicev1.0.0Franchise operating system (franchises and employees, pricing, products and learning books, school operations). Publishe...PublishesGrantApplicationAccess, EmployeeCreated +6SubscribesInviteUser, FranchiseCreated +9Ownercna-platformMapRepoView docs publishes it from syncInviteUserToPerson, right after mirroring an InviteUser into a person and an employee. The access is requested on every invite, whether the person is new or already known, because provisioning the login is cna-auth’s job and this command is what tells it to. origin is the system the invite came from, read from the InviteUser envelope: today metadata.owner (hard-coded by the publishers to their own name, fallback ONE), metadata.producedBy once the envelope change lands.
What the consumer does. cna-auth (accountConsumer, handler grantApplicationAccess):
- Looks the application up by
payload.application(applications.identifier). Unknown application: logged and dropped. - Checks
payload.originagainst the application’sallowedOrigins(uppercase). Origin not allowed: logged and dropped. These two checks run before anything is written, so a rejected command leaves no account behind. - Finds or creates the
Accountbydocument(with its OTP authentication method) and theUserinside it, storingname,employeeIdandidas the person id. - Records the
ApplicationGrant. The application only has to exist;isActiveis a sign-in rule, so a grant on an inactive application becomes usable when it is turned back on.
Every failure is a log and a return. The consumer commits the offset either way, so there is no retry.
Kafka
Topic (aggregateRoot) | Application |
Message key (routingKey) | payload.document |
| Contract owner | AUTH |
metadata.event | GrantApplicationAccess |
| Consumer group | auth-user-events |
Payload schema
Source of truth
export type ApplicationAccessPayload = { id: string; name: string; email: string; document: string; employeeId: string; application: string; origin: string;};
class GrantApplicationAccess extends Event<ApplicationAccessPayload> { public static owner = "AUTH"; public static aggregateRoot = "Application"; public static routingKey = "document";}The copies in cna-auth and cna-one are identical.
Custom properties
| Property | Value |
|---|---|
| Contract Ownerx-contract-owner | AUTH |
| Kafka Topicx-kafka-topic | Application |
| Message Keyx-message-key | document |
| Sourcex-source | cna-auth api/app/events/auth/application/GrantApplicationAccess.ts |
Id of the person in the publishing application (cna-one Person.id). Stored on the account as its person id.
Full name of the person (name and surname joined).
E-mail the login is provisioned on. Taken from the invite, not from what the publisher stores.
Person document (CPF). Kafka message key and the field both systems correlate the person by.
CNA One employee id the access is keyed by. Stored on the account.
Identifier of the application in cna-auth (applications.identifier), e.g. cna-one.
System requesting the access: ONE, NEXUS or PLACEMENT. Must be one of the application's allowed origins; compared uppercase.