Internal · Access Control & SSO
Admin · Staff Portal · Access Control

Access Control & SSO

Role-based access tied to Google Workspace. SSO required to view any page on the staff portal. Per-resource permissions enforced server-side. Audit log records every access.

7Active staff
5Distinct roles
2FARequired for all
SSOGoogle Workspace

SSO sign-in flow

01

Visit /admin

Cloudflare Access intercepts. No CAM session cookie? Redirects to Google.

02

Google sign-in

User's @cmgcam.com Workspace account. 2FA enforced by Workspace.

03

Group check

Cloudflare Access checks Workspace group membership. Outside cam-staff@ = denied.

04

JWT issued

Signed JWT with user email, role, properties. Sent in cf-access-jwt-assertion header.

05

App authorizes

Pages Function reads JWT, looks up per-resource permissions, returns content or 403.

Roles (5)

role
Operations Director
Tizi Goncalves
1 user

Full access. Sees leadership dashboard, all properties, all financials, all audit logs. Can change other users' roles.

role
Manager
Melissa Lopez · Patty Swain · 2 others
4 users

Full access on assigned properties. Cannot view other managers' portfolios. Cannot change permissions.

role
Accountant
Kyle Anderson
1 user

All financials, all properties. Bill approval workflow access. No board-onboarding edits, no welcome packets.

role
Front Desk Pool
Plaza Tower · Tallahassee Center concierges
~6 users · shared

Read-only on their property's owner directory. Read/write on own concierge logs + package log. No financials, no NOLAs.

role
Board liaison (per assoc)
Designated BOD officer per association
~18 users · external

Read-only on their association's BOD-level financials, minutes, manager reports. No other associations.

Permission matrix

Resource Ops Director Manager Accountant Front Desk Board liaison
Operations Manual
Read-only reference
FullFullFullRead
Owner ledgers
Names, balances, payment history
AllOwn propsAllOwn prop · names only
Long Financials
Full P&L · BOD-only
AllOwn propsAllOwn assoc
Short Financials
Member-side summary
AllOwn propsAllOwn propOwn assoc
Mailings (NOLA, budget, etc.)
Page-per-Page console
FullOwn propsRead
Welcome packet onboarding
Send + track
FullOwn propsOwn prop · view
Audit Log
Compliance trail
AllOwn actionsOwn actions
Notification settings
Per-user prefs
Self + othersSelf onlySelf onlySelf onlySelf only
Strategy Brief / Marketing
/opportunities, /marketing, /campaigns
FullRead
Competitor targeting
Sunbiz cross-ref · Lead gen
Full
Access control (this page)
Edit roles & permissions
FullReadRead

Active sessions · last 24h

UserRoleLast loginDeviceIP region2FA
tizi@cmgcam.comOperations DirectorToday 08:42macOS · SafariTallahassee, FLRevoke
melissa@cmgcam.comManagerToday 08:01iOS · MobileTallahassee, FLRevoke
patty@cmgcam.comManagerToday 08:18iOS · MobileTallahassee, FLRevoke
kyle@cmgcam.comAccountantYesterday 17:34Windows · ChromeTallahassee, FLRevoke
frontdesk@plaza-tower.comFront Desk PoolToday 07:55iPadTallahassee, FLRevoke

Wire-up steps for production

  1. Cloudflare Access — enable at cmg.ittlh.dev/admin/* + /onboarding/admin* + /api/notify* (free tier, first 50 users).
  2. Identity provider — connect Google Workspace as IdP. Restrict to @cmgcam.com domain. Enforce 2FA at the Workspace level.
  3. Workspace groups — create cam-staff@, cam-managers@, cam-leadership@, cam-frontdesk@, cam-accountant@. Assign each user to the right group.
  4. Cloudflare Access policies — one policy per role with the matching Workspace group + the page-glob it can reach.
  5. JWT verification middleware — Pages Function at functions/_middleware.js reads cf-access-jwt-assertion header, validates against Cloudflare's public key, attaches the user to the request context.
  6. Per-resource auth — every Pages Function checks request.user.role + the requested resource's allowed roles before responding.
  7. Audit log — every authenticated request writes to the audit-log D1 table with user, path, method, response status, timestamp.
Why Cloudflare Access vs. building auth ourselves: Workspace already has SSO + 2FA + group management baked in. Cloudflare Access is free for the first 50 users, takes ~30 minutes to set up, and removes auth bugs from CAM's risk surface entirely. Auth is the wrong place to be clever.