Why permissions matter for annotations

An annotation is a record of someone's decision: this is a stop sign, this asset is in poor condition, this feature is approved for production. The decision is only as trustworthy as the chain of accountability behind it.

Permissions are how the system enforces accountability. They control who can create annotations, who can modify them, who can approve them, and who can override the approval if it turns out to be wrong. The audit trail captures every decision so the chain is reconstructable later.

This article walks through the permission model we use by default. It's flexible enough for most projects, structured enough that you don't need to design from scratch.

The five standard roles

Viewer

Can see annotations on the map. Cannot create, edit, or comment. Used for stakeholders who need visibility but aren't part of the annotation workflow — managers, clients, auditors.

Annotator

Can create new annotations, edit their own annotations while in draft state, and submit annotations for review. Cannot modify another annotator's work or approve their own. The most common role — typical project has 4-10 annotators in this tier.

Reviewer

Can review submitted annotations: approve, flag for revision, or reject with notes. Can edit annotations during review (correct minor issues without bouncing back to the annotator). Cannot create new annotations in production batches (reviewers stay separate from production work to keep the QA pass independent).

Senior Reviewer

Can do everything a reviewer can do, plus: override schema rules where edge cases warrant it, lock annotations to final state (preventing further edits), modify the schema itself, and edit any annotation regardless of who created it. Typically 1-2 per project — the spatial QA team.

Admin

Project-level admin: add and remove users, change role assignments, modify project settings, export the full data set, view system audit logs. Doesn't necessarily do annotation work — often a project manager or technical owner.

Scope: what permissions apply to

Permissions can be scoped at three levels.

Project scope — a user has a role within a specific project. Most permissions live here. A user might be an Annotator on Project A and a Reviewer on Project B simultaneously.

Layer scope — within a project, permissions can vary by layer. On a multi-class project, you might have one team annotating road signs and a different team annotating utility assets. Each team only sees and edits their layer.

Geometry scope — for large projects we sometimes add geographic scoping. A user is assigned to a region, can only see and edit annotations within that region. Used for projects covering a state or country where workload is naturally split by geography.

The three scopes compose. A user can be a Reviewer on Project A, restricted to the road signs layer, restricted to a specific county. All three constraints apply.

What the audit trail captures

Every action that changes an annotation produces an audit log entry. The schema is:

audit_log
  id, annotation_id, actor_user_id, action_type,
  timestamp, payload_before, payload_after,
  session_id, ip_address, user_agent

Action types include: created, attribute_edited, geometry_edited, status_changed, comment_added, approved, rejected, flagged, locked, unlocked.

Payload before and after capture the full annotation state at the moment of change. This is more storage than just recording the diff, but it makes audit queries cheap (no need to walk the change history backward to reconstruct state at time T) and survives schema migrations cleanly.

Audit logs are immutable. There's no UI to edit or delete them. If a log entry is genuinely wrong (a misattributed change because a service account did something), you append a correction note — you don't rewrite history.

Common patterns

Four-eyes for approvals

For high-stakes projects (regulatory submissions, courtroom exhibits, safety-critical inventories), we configure the workflow so an annotation requires approvals from two reviewers before moving to locked-final state. The second reviewer can see the first's notes but starts from a clean review screen. This is the four-eyes principle — two independent confirmations before the decision is final.

Annotator self-review window

By default an annotator can edit their own work until they submit it for review. After submission, they can no longer edit. This catches the common mistake of "I noticed an error after I submitted" — the annotator either contacts a reviewer to fix it, or the reviewer flags it back to them.

Read-only after final lock

Once an annotation is locked-final by a senior reviewer, it's read-only for everyone except the project admin. Even another senior reviewer can't change it without an admin unlock. This protects the deliverable from late-stage changes that bypass QA.

Some projects don't need this — research data, ongoing field surveys, anything where the data is expected to evolve. Configure per-project.

Time-bound elevated permissions

For audits or one-off corrections, a senior reviewer can grant themselves time-bound elevated permissions (e.g., 24 hours of admin rights). The grant is logged and auto-expires. Cleaner than maintaining a list of "users who used to be admins but aren't anymore."

Integration with existing auth

Permissions live in the annotation system; identity comes from your existing auth. We integrate with OAuth (Google, Azure AD), SAML, ArcGIS Online identity, and JWT-token-based custom systems.

When a user logs in, their identity (email, organization, group memberships) is passed to the annotation system. We map external groups to internal roles (e.g., "anyone in the gis-team Active Directory group gets the Annotator role automatically"). This means user provisioning happens in your normal way — adding someone to AD makes them an annotator without a separate signup.

What permissions don't solve

Two things to be aware of.

Permissions don't solve delegation accountability. If an admin shares their account, the audit log says the admin did the action. We can't prevent password sharing through technical means. For environments where that matters (regulatory, defense), we require SSO with hardware-token MFA.

Permissions don't solve schema disputes. If two senior reviewers disagree about how to classify an edge case, the system records both opinions but doesn't pick a winner. A human (usually the project lead) needs to make the call. We surface the disagreement clearly so it doesn't get lost.


Need a custom permission model? The defaults cover most cases. For projects with regulatory, multi-tenant, or defense requirements, we configure beyond defaults. Send your access requirements and we'll come back with a workable design.