Skip to content

Identity and Access Management Behaviors

Use cases and scenarios for the OAM::IAM (Identity and Access Management) area of the Functional Domain Taxonomy. This area covers user registration, authentication, password management, account profile maintenance, company administration, invitation workflows, and the channels through which new tenants are acquired.

A new user creates an Arda account, either by submitting registration details directly or by authenticating through an external identity provider (Google, LinkedIn, GitHub, Apple). On completion, the user’s account is confirmed, a tenant record is created if the user is starting a new company, and the user is presented with the application dashboard. Registration is the entry point for the Freemium self-service acquisition channel.

PersonaAlan Adminson (Account Admin)
StatusCovered

OAM::IAM::0001::0001.US — Register with Local Credentials

Section titled “OAM::IAM::0001::0001.US — Register with Local Credentials”

The user navigates to /signup, fills in their first name, last name, email address, and password, checks the Terms and Conditions checkbox, and submits the form. The BFF calls Auth.signIn against AWS Cognito, which creates an unconfirmed user record and sends a verification code by email or SMS. After confirmation (either automatically in the initial implementation, or by the user clicking a verification link), a Post Confirmation Lambda invokes the Arda API to create the user account entity.

Once the account is confirmed, the user is shown a Terms and Conditions acceptance and a profile form. After accepting and submitting, the BFF calls createTenant if the user is creating a new company, or getTenantByJoiningKey if they are joining an existing one. An AgentFor association is created linking the user account to the tenant. The user is then directed to the initial organization configuration step (see RES::FAC::0001) and then to the application dashboard. The browser navigates to /signup/success after the form submission; full login requires email verification.

OAM::IAM::0001::0002.US — Register via Social Login (SSO)

Section titled “OAM::IAM::0001::0002.US — Register via Social Login (SSO)”

The user navigates to /signup and clicks a social login button (GitHub, Google, or Apple). The browser initiates an OAuth/OpenID Connect flow, redirecting the user to the identity provider’s authorization page. After the user authorizes the Arda application, the provider redirects back to Arda with an authorization code or ID token. The BFF exchanges this with Cognito for a Cognito JWT set. The remainder of the flow continues identically to local credential registration: profile collection, T&C acceptance, tenant creation, and dashboard presentation.

This scenario is currently not fully implemented. The OAuth flow requires real identity provider interaction that cannot be intercepted in mock mode. Social login buttons render on the signup page but the provider redirect cannot be completed in automated tests.

OAM::IAM::0001::0003.UC — Sign Up with Local Credentials (Sequence)

Section titled “OAM::IAM::0001::0003.UC — Sign Up with Local Credentials (Sequence)”

Full interaction sequence for registering a new Arda account using email and password. Includes Cognito verification (auto-confirm in initial implementation, or user-confirm), Post Confirmation Lambda to create the user account entity, T&C acceptance, profile submission, tenant creation (new) or retrieval (joining), AgentFor association, and initial organization configuration.

Pre-condition: The user has no existing Arda account.

Post-condition: A confirmed user account exists; a tenant and initial organization configuration are created; the user is presented with the application dashboard.

PlantUML diagram

Sub-scenario showing how the initial operations configuration is built for a new tenant.

PlantUML diagram

Minimal Organization and Facility Configuration

Section titled “Minimal Organization and Facility Configuration”

The diagram below shows the minimal tenant configuration: a single facility with a Receiving source station, a Shipping sink station, a Transfer Loop, and a Purchase Queue.

PlantUML diagram

Alternate Minimal Configuration with One Internal Station

Section titled “Alternate Minimal Configuration with One Internal Station”

A slightly more complex configuration with an internal station and two Kanban loops (inbound and outbound) for more detailed consumption tracking.

PlantUML diagram

OAM::IAM::0001::0004.UC — Register via Social Login — SSO Entry Point (Sequence)

Section titled “OAM::IAM::0001::0004.UC — Register via Social Login — SSO Entry Point (Sequence)”

Partial interaction sequence covering the SSO-specific entry point for sign-up. After the user authorizes the external identity provider and is redirected back to Arda, the flow continues identically to OAM::IAM::0001::0003 from the verification step onward.

Status: Not fully implemented. OAuth flow requires live identity provider interaction that cannot be completed in automated test mode.

Pre-condition: The user navigates to /signup and clicks a social sign-up button.

Post-condition: The browser presents the Arda onboarding page; the remainder of the flow continues as per the local credentials sign-up scenario.

PlantUML diagram

An existing user signs in to Arda to access a protected page. The system validates credentials via Cognito, exchanges them for JWT tokens (ID token, access token, and refresh token), stores them in localStorage, and redirects the user to their destination. If the user is not authenticated when accessing a protected resource, they are redirected to the sign-in page with the target URL preserved for post-login redirect.

PersonaAlan Adminson (Account Admin)
StatusCovered

OAM::IAM::0002::0001.US — Sign In with Valid Credentials

Section titled “OAM::IAM::0002::0001.US — Sign In with Valid Credentials”

The user navigates to /signin and enters a valid email and password. The BFF calls Auth.signIn against Cognito, which returns three JWT tokens. The tokens (accessToken, idToken, refreshToken) and userEmail are stored as individual top-level keys in localStorage. The browser navigates to /items (or to the originally requested URL if the user was redirected from a protected route). The sidebar, header bar, and item grid are visible and functional.

OAM::IAM::0002::0002.US — Sign In with Invalid Credentials

Section titled “OAM::IAM::0002::0002.US — Sign In with Invalid Credentials”

The user enters an incorrect email or password on /signin and submits the form. The BFF receives an authentication error from Cognito. The browser remains on /signin. An error message is displayed as a toast or inline message indicating that the credentials are invalid. No tokens are stored in localStorage. The form fields remain editable for retry.

OAM::IAM::0002::0003.US — Sign In via External Identity Provider

Section titled “OAM::IAM::0002::0003.US — Sign In via External Identity Provider”

The user clicks “Login with External IDP” on the sign-in page. The browser redirects to the external provider (Google, LinkedIn, etc.) to initiate an OAuth/OpenID Connect flow. After the user authenticates with the provider, the browser is redirected back with an authorization code or ID token. The BFF sends this to Cognito for federation, which validates the external token with the provider and returns a Cognito JWT set. The tokens are stored and the user is redirected to /items.

The user opens the sidebar, clicks the user section at the bottom, and selects “Log out.” All tokens (accessToken, idToken, refreshToken) and userEmail are removed from localStorage. The browser redirects to /signin. Any subsequent navigation attempt to a protected route redirects back to /signin. This confirms that the session is fully cleared on the client side.

OAM::IAM::0002::0005.FS — Handle Expired Session

Section titled “OAM::IAM::0002::0005.FS — Handle Expired Session”

The user is authenticated but their access token has expired and the refresh token is also invalid or expired. When the user performs any action that triggers an API call, the server returns a 401 Unauthorized response. The authErrorHandler intercepts the error, clears all tokens from localStorage, and automatically redirects the user to /signin. No ?next= redirect parameter is preserved. A message may indicate that the session has expired.

OAM::IAM::0002::0006.FS — Session Auto-Refresh

Section titled “OAM::IAM::0002::0006.FS — Session Auto-Refresh”

The useAuthValidation hook polls token validity every 15 minutes. When the access token is approaching expiry but the refresh token remains valid, the hook automatically exchanges the refresh token for new credentials via Cognito. New accessToken and idToken are stored in localStorage, replacing the previous values. The user’s session continues without interruption and no visual indication of the refresh is shown. This scenario is currently out of scope for automated testing because MockAuthProvider uses long-lived tokens that do not expire during test sessions.

Automatic testing: Out of scope. Token refresh endpoint is deferred.

OAM::IAM::0002::0007.UC — Sign In with Unauthorized Access Redirect (Sequence)

Section titled “OAM::IAM::0002::0007.UC — Sign In with Unauthorized Access Redirect (Sequence)”

Full interaction sequence covering an unauthorized access attempt, the sign-in flow (local credentials and external IDP paths), JWT storage, and subsequent successful access to the protected resource. Includes both the 401 detection/redirect path and the successful post-authentication redirect back to the originally requested URL.

Pre-condition: The user attempts to access a protected resource without a valid JWT, or navigates to the sign-in page directly.

Post-condition: The user holds a valid JWT set in localStorage and is viewing the originally requested protected resource (or the dashboard if no specific resource was requested).

PlantUML diagram

Users can reset forgotten passwords via a token-sent-by-email flow and can change their current password from within account settings while maintaining their active session.

PersonaAlan Adminson (Account Admin)
StatusCovered

OAM::IAM::0003::0001.US — Reset Forgotten Password

Section titled “OAM::IAM::0003::0001.US — Reset Forgotten Password”

The user navigates to /reset-password, enters their email address, and submits the form. The browser navigates to /reset-password/email-sent and displays a confirmation message instructing the user to check their inbox. A password reset token has been generated server-side and an email has been sent to the provided address. The reset token is single-use and time-limited.

OAM::IAM::0003::0002.US — Complete Password Reset

Section titled “OAM::IAM::0003::0002.US — Complete Password Reset”

The user receives a password reset email, clicks the link, and is taken to /reset-password/new with a valid reset token in the URL. The page shows “new password” and “confirm password” fields. The user enters a new password meeting validation requirements (minimum 8 characters, uppercase, lowercase, number, and special character), confirms it, and submits. The browser navigates to /reset-password/success. The user’s password is updated in Cognito and the reset token is consumed and cannot be reused. A link to /signin is available on the success page.

OAM::IAM::0003::0003.US — Change Password from Account Settings

Section titled “OAM::IAM::0003::0003.US — Change Password from Account Settings”

The user navigates to /account-profile or the Account tab in /settings. A “Change Password” section is visible below the profile form, with fields for current password, new password, and confirm new password. The user fills in all three fields and clicks “Change Password.” The password is updated server-side and a success toast confirms the change. The password fields are cleared. The user’s session remains active — tokens are not invalidated by a password change in this flow.

OAM::IAM::0004 — Account Profile and Preferences

Section titled “OAM::IAM::0004 — Account Profile and Preferences”

Users can update their personal profile information and configure application-level personal preferences such as theme, font size, and notification channels. These settings are scoped to the individual user account.

PersonaAlan Adminson (Account Admin)
StatusCovered

OAM::IAM::0004::0001.US — Update Account Profile

Section titled “OAM::IAM::0004::0001.US — Update Account Profile”

The user navigates to /account-profile or the Account tab in /settings. The page shows a form with Name, Date of Birth, and Language fields pre-populated with current values. The user modifies one or more fields and clicks “Update account.” A PUT /api/user/:userId request is sent with the updated data. A success toast confirms the update. The new values are reflected in the form. If the language preference was changed, the UI updates to reflect the new locale.

OAM::IAM::0004::0002.US — Change Appearance Settings

Section titled “OAM::IAM::0004::0002.US — Change Appearance Settings”

The user navigates to /settings and clicks the “Appearance” tab. The tab presents visual preferences including theme (light/dark), font size, and color scheme. The user selects a new preference. The change is applied to the UI immediately. The preference is persisted to the user account and survives page reloads and browser restarts.

OAM::IAM::0004::0003.US — Configure Notification Preferences

Section titled “OAM::IAM::0004::0003.US — Configure Notification Preferences”

The user navigates to /settings and clicks the “Notifications” tab. The tab lists notification categories (order status changes, system alerts, etc.) with toggles per delivery channel (in-app, email). The user enables or disables individual preferences and saves. Future events of the configured types are suppressed or delivered according to the saved settings.

OAM::IAM::0005 — Company and Tenant Administration

Section titled “OAM::IAM::0005 — Company and Tenant Administration”

Account administrators can update company information and manage the list of users associated with the tenant from the Company Settings page. The subscription and billing information is covered in the Accounting area.

PersonaAlan Adminson (Account Admin)
StatusCovered

OAM::IAM::0005::0001.US — Update Company Settings

Section titled “OAM::IAM::0005::0001.US — Update Company Settings”

The user navigates to /company-settings. The Company info tab is active by default and shows a form with fields for Company Name, Address, City, State, Zip code, and Country, pre-populated with current values. Four tabs are visible: Company info, Users, Subscription, and Billing. The user modifies one or more fields and clicks “Save.” A tenant update API call is sent and a success toast confirms the change. Other users in the same tenant see the updated company information on their next page load.

OAM::IAM::0005::0002.US — Manage Company Users

Section titled “OAM::IAM::0005::0002.US — Manage Company Users”

The user navigates to /company-settings and clicks the “Users” tab. A user management interface displays the list of users in the company, with options to invite new users, modify roles, or remove users. This scenario is currently out of scope for automated testing because user management endpoints (/api/arda/user-account/*) are not mocked.

Automated testing: Out of scope. User management endpoints deferred.

OAM::IAM::0006 — Invite User to Organization

Section titled “OAM::IAM::0006 — Invite User to Organization”

An account administrator invites an external user to join their organization by email. The invitee receives an email with an accept/decline link. If the invitee has an existing Arda account they follow the accept link directly; if not, they are directed to the registration flow first and then to the accept/decline page.

PersonaAlan Adminson (Account Admin)
DependsOAM::IAM::0001
StatusCovered

OAM::IAM::0006::0001.US — Send Invitation

Section titled “OAM::IAM::0006::0001.US — Send Invitation”

The host user navigates to the Organization page (Workspace Settings) and clicks “Invite User.” An invitation form appears with a default email message. The host enters one or more email addresses and optionally edits the default message, then submits. The BFF calls InviteUser(email, message) on the Arda API. The Accounts service generates accept and decline URLs, sends the invitation email via the external messaging system, and registers a pending invitation record in the system.

Pending invitations that have not been accepted or rejected appear in the invitee’s notification inbox once they log in.

OAM::IAM::0006::0002.US — Accept Invitation (Existing User)

Section titled “OAM::IAM::0006::0002.US — Accept Invitation (Existing User)”

The guest user clicks the accept invitation link in their email. The browser navigates to the Arda accept invitation page. The user confirms their intent and the BFF calls AcceptInvitation(inviteId). The invitation record transitions to ACCEPTED, the user’s account is linked to the host’s tenant via a new AgentFor association, and the user is redirected to the application dashboard with access to the host’s organization.

OAM::IAM::0006::0003.US — Accept Invitation (New User)

Section titled “OAM::IAM::0006::0003.US — Accept Invitation (New User)”

The guest user receives an invitation email for an email address that has no existing Arda account. The email contains a sign-up link. The user follows the link and completes the registration flow (see OAM::IAM::0001). After account creation, the user is directed to an accept/decline invitation page and follows the same acceptance flow as an existing user. Upon acceptance, an AgentFor association is created and the user is taken to the dashboard with the host tenant’s organization.

OAM::IAM::0006::0004.UC — Invite User to Organization (Sequence)

Section titled “OAM::IAM::0006::0004.UC — Invite User to Organization (Sequence)”

Full interaction sequence for the invitation workflow: the host initiates the invitation, the system generates accept/decline URLs and sends the invitation email, and the guest accepts the invitation (covering the path where the guest already has an Arda account).

Note: The External Messaging System should be replaced with HubSpot to track customer activity.

Pre-condition: The host is logged in and has administrator rights for the tenant. The guest’s email address is known.

Post-condition: If accepted: a new AgentFor record links the guest account to the host’s tenant and the guest is redirected to the application dashboard. Pending (unaccepted) invitations appear in the guest’s notification inbox.

PlantUML diagram

A user who does not have an invitation can request to join an existing organization by providing the organization’s name. The system notifies the tenant administrator, who reviews and either approves or rejects the request. The request mechanism can be initiated during sign-up (for a user creating their first account) or from within an existing account (to join an additional organization).

PersonaAlan Adminson (Account Admin)
DependsOAM::IAM::0001, OAM::IAM::0006
StatusCovered

OAM::IAM::0007::0001.US — Request to Join at Sign-Up Time

Section titled “OAM::IAM::0007::0001.US — Request to Join at Sign-Up Time”

During the sign-up flow, after accepting the Terms and Conditions, the user selects “Join Existing Organization” instead of creating a new company. The user enters the unique company name registered in the system (no autocomplete is provided to avoid revealing registered company names). The system creates a user account without a default tenant, creates a join request record in PENDING state, and notifies the organization’s administrator via the external messaging system. The user receives a confirmation that their request has been received and will hear back by email. The user account exists but has limited access until approved.

OAM::IAM::0007::0002.US — Request to Join After Sign-Up (Additional Organization)

Section titled “OAM::IAM::0007::0002.US — Request to Join After Sign-Up (Additional Organization)”

An existing logged-in user navigates to the “Join Organizations” page from their account profile. The user enters an organization name and an optional request message and submits. The BFF calls createJoinRequest(orgId, userId, message), which creates a PENDING join request and notifies the organization admin. The user can see the pending request in their account settings or notification inbox.

OAM::IAM::0007::0003.US — Review and Accept Join Request

Section titled “OAM::IAM::0007::0003.US — Review and Accept Join Request”

The tenant administrator navigates to the “Pending Requests” page. The page displays a list of open join requests retrieved from listPendingRequests(). The admin selects one or more requests and clicks “Accept.” For each accepted request, the system sends acceptJoinRequest(requestIds) to the API, which transitions each request to ACCEPTED and sends a notification to the requester. The accept action follows the same path as the invitation acceptance flow, creating AgentFor associations and granting the user access to the tenant. The pending requests list is refreshed after the operation.

OAM::IAM::0007::0004.US — Review and Reject Join Request

Section titled “OAM::IAM::0007::0004.US — Review and Reject Join Request”

The administrator reviews pending join requests and selects one or more to reject. Clicking “Reject” sends rejectJoinRequest(requestIds) to the API, which transitions each request to REJECTED and notifies the requesting user. The rejection message is intentionally identical to the message sent when the company name does not exist in the system, to avoid revealing information about registered company names. The pending requests list is refreshed.

OAM::IAM::0007::0005.UC — Accept or Reject Joining Request (Sequence)

Section titled “OAM::IAM::0007::0005.UC — Accept or Reject Joining Request (Sequence)”

Full interaction sequence for the tenant administrator reviewing pending join requests and accepting or rejecting them. The admin can optionally fetch details for a specific request before acting. Both accept and reject actions notify the requester via the external messaging system and refresh the pending requests list.

Note: The External Messaging System should be replaced with HubSpot to track customer activity.

Pre-condition: The tenant administrator is logged in. One or more join requests exist in PENDING state.

Post-condition: Selected join requests are transitioned to ACCEPTED or REJECTED. Requesters are notified. The pending requests list is refreshed.

PlantUML diagram

OAM::IAM::0008 — Customer Acquisition Channels

Section titled “OAM::IAM::0008 — Customer Acquisition Channels”

New tenants are onboarded through two distinct channels: Straight Sale (a sales-assisted process tracked via HubSpot, used for paying customers) and Freemium self-service sign-up (the self-serve path documented in OAM::IAM::0001). The channel determines the onboarding experience, CRM tracking, and initial plan assignment.

PersonaAlan Adminson (Account Admin)
StatusNew-distinct

OAM::IAM::0008::0001.US — Freemium Self-Service Sign-Up

Section titled “OAM::IAM::0008::0001.US — Freemium Self-Service Sign-Up”

A prospective customer discovers Arda through marketing, navigates to https://arda.cards/signup, and completes registration without any sales interaction. The account is created on the Freemium plan with default feature limits. The sign-up event is tracked in HubSpot (replacing direct email notifications) to initiate the CRM record and customer lifecycle tracking.

OAM::IAM::0008::0002.US — Straight Sale Onboarding

Section titled “OAM::IAM::0008::0002.US — Straight Sale Onboarding”

A customer is acquired through direct sales contact. The sales process is managed in HubSpot. At the conclusion of the sale, the customer receives a personalized onboarding link that pre-populates tenant configuration or assigns the account to a paid plan. This channel may bypass parts of the standard self-service registration flow.

Note: The detailed flow for Straight Sale onboarding is not yet documented.

Use CaseScenariosUSFSUC
OAM::IAM::0001 User Registration4202
OAM::IAM::0002 User Authentication7421
OAM::IAM::0003 Password Management3300
OAM::IAM::0004 Account Profile and Preferences3300
OAM::IAM::0005 Company and Tenant Administration2200
OAM::IAM::0006 Invite User to Organization4301
OAM::IAM::0007 Join Request Lifecycle5401
OAM::IAM::0008 Customer Acquisition Channels2200
Total302325