Skip to main content

Identity, Authentication & Access

Nothing in the platform trusts an application because of where it runs. Every request to a digital farm API carries a token issued by an identity provider, and the API decides — from the token and from the data model's own roles — what the caller may do.

This follows the security provisions of the Recommendation (clause 10): the use of an external identity and access management system is mandatory, and it is spoken to through OpenID Connect. The APIs do not store passwords, run log-in screens or issue tokens; they only verify tokens.

The pieces​

PieceRole
PersonFarmer, employee, adviser, contractor — a User in the data model. Signs in at the identity provider and nowhere else.
Identity provider (the issuer)An OpenID Connect / OAuth 2.0 service. Authenticates people, asks for their consent, issues tokens, signs them with keys it publishes.
First-party appThe platform's own app (phone, web, desktop). A public client. See Signing in people.
External appAn app built by somebody else — a web app with a backend, or a plain link. Registered with the platform; if it has a backend, a confidential client. See Signing in apps.
Digital farm APIA resource server: it verifies tokens and serves the data model. Identified by an audience.
App registry (App Store)Optional control plane: registers apps, has them reviewed, sets up their clients and scopes at the identity provider. At run time it is not involved.
              ┌───────────────────────────────────────────────┐
│ Identity provider │
│ OpenID Connect · OAuth 2.0 · signing keys │
└─────▲────────────────▲───────────────────▲────┘
sign in, │ sign in, │ │ keys,
tokens │ exchange │ │ discovery
┌─────┴──────┐ ┌─────┴──────┐ │
Person ────▶ │ First-party│ │ External │ │
│ app │ │ app │ │
└─────┬──────┘ └─────┬──────┘ │
│ Bearer token │ Bearer token │
▼ ▼ │
┌──────────────────────────────────────────┴────┐
│ Digital farm API │
│ verifies the token, then checks the farm │
│ permissions (Role, AccessAssignment) │
└───────────────────────────────────────────────┘

Standards, not products​

The identity layer is built from open standards only. Any identity provider that implements them can be used; any client library that implements them can talk to it.

StandardUsed for
OAuth 2.0 (RFC 6749)the framework: clients, grants, scopes, tokens
Bearer Token Usage (RFC 6750)Authorization: Bearer … on every API call
OpenID Connect Core 1.0authenticating the person; the ID token; private_key_jwt client authentication
OpenID Connect Discovery 1.0finding the endpoints and keys from the issuer URL alone
PKCE (RFC 7636)binding an authorization code to the client that asked for it — on every sign-in
OAuth 2.0 for Native Apps (RFC 8252)signing in from a phone or desktop app through the system browser
OAuth 2.0 Security Best Current Practice (RFC 9700)exact redirect-URI matching, no implicit or password grant
JSON Web Token (RFC 7519), JWS, JWKthe token format, its signature and the published keys
JWT client authentication (RFC 7523)how a confidential app proves who it is, without a shared secret
Token Exchange (RFC 8693)an app asks for a token cut to one service and its scopes
Client credentials (RFC 6749 §4.4)an app acting as itself, with no person
Device Authorization Grant (RFC 8628), with PKCEdevelopers signing in from a command line
Issuer Identification (RFC 9207)the iss parameter on the authorization response
OpenID Connect Back-Channel Logout 1.0the identity provider tells apps that a session ended
OpenID Connect RP-Initiated Logout 1.0an app ends the person's session at the identity provider
Problem Details (RFC 9457)how the API reports 401, 403 and everything else — see Errors

Authentication and authorisation are separate decisions​

  1. The identity provider decides who the caller is — and what an app may ask on a person's behalf. It issues a token only for scopes the person has consented to.
  2. The API checks the token: signature against the issuer's published keys, iss, exp, its own audience in aud, then the scopes the operation needs. See Scopes, audiences & permissions.
  3. The data model decides what that person may do on which farm. Role and AccessAssignment give a base layer inside the model; they are evaluated in addition to, never in place of, the identity provider's policies.

A rule that works well: let the service decide from the intersection of what the person may do and what the token's scopes grant. An app can then never do more than the person, and never more than its scope says.

Roles and access in the data model​

// Role
{
"id": "a67dcd3e-3a44-5196-b5b8-423fefd2f99f",
"name": "farm manager",
"permissions": ["farm:read", "field:read", "field:update", "task:create",
"task:update", "activity:create", "activity:read",
"regulatoryReport:read"],
"isSystemRole": true
}

// AccessAssignment — this user holds that role on this farm, from this date
{
"userId": "b630da76-9ec3-5faa-a1d7-e66d56bc5db4",
"farmId": "997142c3-14cf-5cb4-b260-048af4b57a76",
"roleId": "a67dcd3e-3a44-5196-b5b8-423fefd2f99f",
"startsAt": "2025-01-15T00:00:00Z"
}
  • A permission has the pattern entity:action — field:read, task:update, regulatoryReport:read. Actions are read, create, update and delete. Each operation of the REST API names the permission it requires in x-agfoda-permission, evaluated per farm.
  • An AccessAssignment gives a user a role on one farm, optionally for a limited time (startsAt, endsAt) — which is how access for advisers and contractors is granted and lapses. Validity periods for the same user, farm and role must not overlap (rule V16).
  • User.email serves as the login identity and is unique within the deployment.
  • Finer than a farm. Farm.iamResourceId registers the farm as a resource at the identity provider, and Data.iamResourceId registers an individual dataset as a protected resource of its own. Policies that depend on attributes or on the purpose of processing stay in the identity layer.

Data sovereignty is technical​

Consent is not a clause in a contract. A person sees which app asks for which data — in the words the service owner wrote for each scope — before a token exists; the token holds only what was agreed; the consent can be revoked at the identity provider, after which the next token exchange fails. Every change to a record is written to the append-only AuditLog. See Data Sovereignty in Practice.

What a platform has to provide​

LevelThe platform providesResult
0an identity provider; the digital farm APIsapps can sign people in and call the APIs; the operator provisions each app's client by hand
1+ an app registrythe developer workflow: register, review, provision, publish
2+ a host appthe in-app experience: apps open inside the platform's own app, with a silent hand-over of the person's sign-in

The requirements on the identity provider, step by step, are in the platform contract.

In this section​

See it in action​