Define and implement read/write authorisation scopes for identifier mapping endpoints
As a security engineer responsible for the Identifiers API,
I would like read and write access to CHRIS/CAMSIS → CRSid mapping endpoints
to be governed by explicit scopes based on approved applications in the API Gateway,
so that only authorised client applications can read
or modify identifier mappings in a consistent,
auditable way across all environments.
Background
- The Identifiers API exposes POST (create) and GET (read) endpoints for CHRIS/CAMSIS → CRSid mappings.
- Authentication must be provided by the API Gateway using
apigatewayauth(specificallyAPIGatewayClientCredentials), not DRF token auth. - The epic requires:
- Gateway-based authentication.
- Read authorisation via approved applications.
- Write authorisation via a static list of writer applications from Terraform.
- Separate read/write scopes and fast failure if configuration is wrong.
- We need:
- A pair of read/write permissions.
- Terraform-managed permission specification.
- DRF permissions that enforce these permissions using the application identity from the gateway.
Acceptance Criteria
-
Two permissions are defined, e.g.: -
IDENTIFIER_MAPPING_READERfor read access. -
IDENTIFIER_MAPPING_WRITERfor write access.
-
-
Semantics are documented: -
IDENTIFIER_MAPPING_READER→ may call GET mapping endpoints. -
IDENTIFIER_MAPPING_WRITER→ may call POST mapping endpoints (and read, if intended).
-
-
REST_FRAMEWORK["DEFAULT_AUTHENTICATION_CLASSES"]is updated to:- Use
APIGatewayClientCredentialsfromapigatewayauth. - Not include DRF token authentication.
- Use
-
REST_FRAMEWORK["DEFAULT_PERMISSION_CLASSES"]is set to a secure default (e.g.apigatewayauth.permissions.Disallowed), forcing explicit permissions on views. -
Terraform in iam/identifiers/infrastructure:- Defines per-environment lists:
-
identifiers_api_reader_applications. -
identifiers_api_writer_applications.
-
- Generates a YAML/JSON permissions file mapping the two permissions to principals/groups.
- Stores this file in a bucket or equivalent and exposes its location to the app via environment/config.
- Defines per-environment lists:
-
The web app ( iam/identifiers/api) includes a small utility to:- Load and parse the permissions file at startup.
- Cache permissions in memory keyed by permission name.
- Look up whether the calling application (from
APIGatewayClientCredentials) has a permission.
-
A fast-failure mechanism is implemented so that missing/invalid permission configuration: - Causes mapping requests to fail with 5xx responses.
- Emits clear, structured error logs.
-
DRF permission classes are added: -
IsIdentifierMappingReaderfor GET endpoints (requiresIDENTIFIER_MAPPING_READER). -
IsIdentifierMappingWriterfor POST endpoints (requiresIDENTIFIER_MAPPING_WRITER).
-
-
Mapping endpoints are updated to use these permission classes and: - Return
403 Forbiddenwhen unauthenticated or lacking the required permission.
- Return
-
Tests cover: - Reader-only app: GET allowed, POST forbidden.
- Writer app: POST allowed; read behaviour matches documented semantics.
- App with neither permission: GET and POST forbidden.
- Behaviour when the permission specification is missing/invalid.
- Authentication path via
APIGatewayClientCredentialsand absence of DRF token auth.
-
Documentation (infra README and API docs) is updated to: - Describe the read/write permissions and how to add/remove applications.
- Explain how the API Gateway,
APIGatewayClientCredentials, application IDs and the two permissions relate.
Edited by Eugene E.