Skip to content

15. Authentication, IAM, and Electronic Signatures

Authentication proves an identity. Directory owns the person. Product IAM resolves what that person may do in one product and scope. An electronic signature re-verifies the authenticated person for one action digest.

Do not collapse these into one user table or one client-side permission flag.

This chapter uses app declarations from vyuh_blueprint, authentication wire types from vyuh_blueprint_protocol, authority/runtime types from vyuh_blueprint_server, and product catalogs from vyuh_iam.

Declare the client authentication boundary

dart
final app = BlueprintDescriptorSet(descriptors).blueprintApp(
  name: 'operations',
  title: 'Operations',
  version: '1.0.0',
  authentication: const AuthenticationUI(
    enabled: true,
    isRequired: true,
    loginPath: '/login',
    callbackPath: '/auth/callback',
    authenticatedPath: '/',
    publicPaths: ['/help'],
    allowPasswordReset: true,
  ),
);

AuthenticationUI declares routes and replaceable widget refs. It does not carry provider secrets, tenant provider availability, or effective session timeouts. Those are server-resolved runtime facts.

Bind the authority on the server

dart
final auth = BlueprintAuthenticationController(
  blueprint: blueprint,
  provider: provider,
  providerCatalog: providerCatalog,
  deploymentEnvironment: 'production',
  sessionPolicyResolver: resolveSessionPolicy,
  policyEnforcer: loginPolicy,
  electronicSignatureStore: signatureStore,
  administratorSupportHandler: createSupportRequest,
);

BlueprintAuthenticationProvider supplies login, begin/complete authentication, refresh, logout, token authentication, and provider identity. Optional provider capabilities supply password reset and credential verification. BlueprintAuthenticationProviderCatalog resolves which declared providers are enabled for the tenant and deployment environment.

The controller derives its public action manifest from the declared auth.identity entity. If a required canonical action is missing, it fails closed rather than exposing a partial contract.

Resolve sessions on the authority

dart
const defaultSessionPolicy = BlueprintAuthenticationSessionPolicy(
  inactivityTimeout: Duration(minutes: 30),
  absoluteTimeout: Duration(hours: 12),
  refreshSkew: Duration(seconds: 30),
  warningDuration: Duration(minutes: 2),
);

Issued and refreshed sessions carry the effective policy. A resolver can vary it by tenant or environment. The client enforces the returned inactivity, absolute timeout, refresh skew, and warning duration; it does not choose them.

Provider discovery and public recovery requests also bind the deployment environment on the server, preventing a client from selecting a different operational boundary.

Map directory identity to a product actor

dart
final strategy = BlueprintAuthenticationStrategy(
  provider: provider,
  actorResolver: (identity) async => resolveOpsActor(
    directoryUserId: identity.directoryUserId!,
    tenantId: identity.tenantId,
  ),
);

The default strategy can create a basic UserActor, but a product resolver is where Directory identity becomes a product IAM principal with effective roles, groups, grants, and scope. Unknown authentication must not enumerate directory users.

Build the product permission inventory

dart
const permissions = IamProductDescriptor(
  product: 'ops',
  title: 'Operations',
  actions: [
    IamActionDescriptor(
      action: 'ops.area.governance.activate',
      title: 'Activate Area',
      entityName: 'area',
      facetName: 'governance',
    ),
    IamActionDescriptor(
      action: 'ops.auth.authentication.login',
      title: 'Sign In',
      resourceType: 'authentication',
      grantEditable: false,
    ),
  ],
);

The same qualified action keys feed grant evaluation and IAM administration. vyuh_iam_ui renders the action catalog, grant editor, principal matrices, role-level editing, and effective permissions. Effective allow/deny remains a server-side decision even when the UI hides or disables an action.

Re-verify a regulated signature

For an action whose AuditEnvelope requires a signature, the client opens the Studio electronic-signature dialog and asks the authority to verify credentials for the already authenticated identity.

The authority returns a one-time BlueprintElectronicSignatureAssertion with:

  • signerId and signerDisplayName;
  • actionDigest and human meaning;
  • authenticatedAt and expiresAt;
  • a one-time ElectronicSignatureProof.

The action request carries that proof. BlueprintElectronicSignatureVerifier checks the proof, action digest, signer, and expiry before the target action is allowed to execute. Reauthentication does not replace the active auth session or ask the client to assert signer facts.

Keep public recovery non-enumerating

Password reset and administrator-contact actions return safe acceptance receipts. Providers and handlers must respond consistently for known and unknown identifiers. Support topics use stable wire values while the UI shows human labels.

Checkpoint

Prove the complete chain:

  1. provider discovery is filtered by tenant and environment;
  2. login returns an effective session policy;
  3. authentication resolves a Directory user and then a product actor;
  4. IAM evaluates the qualified action with tenant/site scope;
  5. a signature-required action binds a fresh assertion to its action digest;
  6. expired, mismatched, or reused signature proof fails closed;
  7. public reset/support flows reveal no account existence.

Next: System readiness and production patterns.

References: Vocabulary · Replay Contract.

Blue is the Vyuh Blueprint documentation surface.