Build

SSO & permissions

Google Workspace and Microsoft 365 SSO, role-based access for seven roles, just-in-time provisioning, and a read-only audit-log API.

Overview

Lectern’s permission model is two layers: identity (who is signing in - via SSO or password) and role (what they can do once authenticated). SSO doesn’t change roles; it just changes how someone proves who they are.

Google Workspace

The fastest setup if your school already runs on Google.

  1. In the Lectern dashboard, open Settings → Integrations → Google Workspace.
  2. Click Connect. You’ll be redirected to Google to authorize Lectern with your admin.directory.user.readonly scope.
  3. Choose which Google groups map to which Lectern roles. Most schools map staff@school.edu teacher, but you can be more granular.
  4. Optionally enable JIT provisioning - new Google accounts in mapped groups become Lectern accounts on first sign-in.

From now on, the Lectern sign-in page shows a Continue with Google button. Email/password fallback remains available unless you disable it in Settings → Authentication.

Microsoft 365

Same pattern, different IdP. Lectern is registered in the Microsoft application gallery; you can install it from your tenant’s admin console or follow the inline OAuth flow from the dashboard.

  1. Open Settings → Integrations → Microsoft 365 and click Connect.
  2. Sign in as a Microsoft 365 administrator and consent to the User.Read.All and Group.Read.All scopes.
  3. Map Microsoft 365 security groups to Lectern roles, same as Google.

SAML for everything else

For Okta, JumpCloud, ADFS, or any IdP that speaks SAML 2.0, configure a custom SAML connection from Settings → Authentication → SAML. Lectern’s ACS URL and entity ID are shown in the dashboard; copy them into your IdP, paste back the metadata, and you’re done.

Just-in-time provisioning

With JIT enabled, the first time a user authenticates via SSO, Lectern creates their account automatically using attributes from the IdP token. The mapping is configurable but the defaults work for most schools:

JSONDefault attribute mapping
Copy
{
  "email": "{{user.email}}",
  "name": "{{user.name}}",
  "role": "{{group.role_mapping}}",
  "school_id": "{{tenant.id}}"
}

Roles

Lectern ships with seven built-in roles. They’re backed by scopes - if you need finer-grained permissions, custom roles are configurable in Settings → Permissions.

system_adminAll tenantsPlatform operator. Manages schools, users, billing.
school_adminSingle tenantDay-to-day operator. Full access to one school.
group_adminFederationParent-school admin. Can read across branches.
bursarFinance moduleInvoicing, bursaries, reconciliation. No academic write.
teacherAssigned classesRead learners in own classes; write grades and attendance.
parentOwn childrenRead-only on linked learners; pay fees; receive comms.
studentSelfRead own records, timetable, results, assignments.

Audit log API

Every state-changing action in Lectern writes an audit-log entry - sign-ins, record updates, fee reconciliations, role changes, everything. The log is read-only via API, with a 90-day default retention (extendable per tenant).

cURLGET /v1/audit
Copy
$ curl "https://api.lectern.school/v1/audit?actor=usr_5f3c&limit=10" \
    -H "Authorization: Bearer sk_live_lectern_…"
Response200 OK
application/json
{
  "data": [
    {
      "id": "aud_8aJ4F",
      "actor_id": "usr_5f3c",
      "action": "learner.update",
      "resource_id": "lrn_8aJ4F",
      "changes": {
        "grade_level": ["10", "11"]
      },
      "ip": "102.176.55.18",
      "at": "2026-05-07T11:42:08Z"
    }
  ]
}

Every entry includes the actor, the action, the resource, the diff, the IP address, and a UTC timestamp. The log is the source of truth for compliance reviews - and yes, it’s POPIA-aligned.

Token & key rotation

  • API tokens - rotate via Settings → API; old tokens are revoked immediately.
  • Webhook signing secrets - rotate per webhook; rotation produces a new secret and a 24-hour grace window during which both old and new signatures are accepted.
  • SSO certificates - for SAML, upload a new cert before the old one expires; both are accepted during overlap.