0.5.0
This release makes the registry's data more reliable for clients. Service
types are stored and can be curated (modes open, controlled and
moderated), the registry sets the timestamps of services, and the
environments of services come from a configurable allow-list. Some of these
changes are breaking (see below). Deployments of 0.4.0 keep their data:
read the upgrade
steps
first, including the check of the stored environments before the upgrade and
the restart after the rollout. See the
documentation for details.
Breaking changes¶
- API: the registry sets the timestamps of services (
createdAtwhen a service is registered,updatedAton every registration and update), as RFC 3339 date-times in UTC, in milliseconds. Timestamps that users other than admins send are ignored (not an error), so they now describe the registry's entry, not the deployment of the service as in the GA4GH specification. Admins can still set them, e.g., to import services, but only as RFC 3339 date-times (400otherwise). Services stored before keep their timestamps until they are updated (#236, #237) - API:
GET /services/typeslists the stored service types, also types that no service has (yet), instead of the types of the registered services. Types stay registered when the services that had them change or are deleted, until admins remove them. On startup, the app stores the types of the registered services (#235, #241) - API: the environment of services (
environment) must be one of the values that the deployment allows (custom.endpoints.services.environments, by defaultprod,test,devandstaging, the values that the GA4GH specification suggests; an empty list allows any value). Registrations with other values return400, naming the allowed values. Stored services with other values are still served, but can only be updated with an allowed value (or withoutenvironment); the app warns of them on startup (#239, #242) - Configuration: overlays that give the policies
(
security.access_control.policies) as a list must add the new rulesadd-service-types(POST /services/types) andlist-approvals(GET /approvals), or users can't add service types or list pending approvals (#235, #241; #238, #244)
Features¶
- Service types:
POST /services/typesregisters a type, and admins remove types that no service has (DELETE /services/types,409 Conflictfor types in use). Registering or updating a service with a new type registers the type, too (#235, #241) - Service types:
custom.access_control.service_typessets who may add types:open(the default) lets any authenticated user add them,controlledonly admins (other users can only register services with stored types), andmoderatedany authenticated user, but the types of users other than admins, and the services that have them, are pending until an admin approves them (PUT /services/types/approval). Pending types are only shown to admins and to the users who added them, pending services only to admins and to the users who have a role on them;GET /approvalslists those a user may see.GET /metells clients whether the current user may add types (may_add_service_types) and whether their new types are pending (service_types_pending) (#235, #241; #238, #244) - Service types: users other than admins may add at most
custom.access_control.max_unused_service_typestypes that no service has (default10,nullfor no limit,0for admins only), in every mode; further types are rejected (409 Conflict). Pending services carry an internal, indexed flag, so that reads don't grow with the number of pending types; the app creates the new indexes and reconciles the flags on startup. Rate-limitPOST /services/typesandPOST /servicesat the ingress, as the limit is per user (#246, #254) - Access control: the public reads (
GET /services,GET /services/{serviceId},GET /services/types,GET /services/{serviceId}/verificationandGET /verifications) accept an optional bearer token and then apply that user's visibility rules, e.g., show the user's pending types and services. Invalid or expired tokens are rejected (401 Unauthorized, with aninvalid_tokenchallenge), so that clients log in again; if the identity provider is unavailable, the request is treated as anonymous (logged at levelINFO). Pending services can't be verified (409 Conflict), and services that become pending lose their verification, also when onlytype.versionchanges (#245, #255) - API: conflicts (
409 Conflict) have a code (code) that tells them apart. Unlikedetail, which is unchanged, codes are stable, so clients can branch on them:duplicate-service,pending-service,unused-types-limit,service-type-registered,service-type-in-use,verification-mismatch,last-owner, andconflictfor other conflicts. The API specification lists them as an extensible enum (schemaConflictError,x-extensible-enum); further codes may be added, so treat unknown ones likeconflict(#247, #258)
Fixes¶
- Release workflow: releases are published only after their assets are uploaded, as immutable releases can't get assets afterwards (#216, #219)
- Release workflow: the generated notes of a first release list all merged pull requests, even if older tags without a release exist (#221, #225)
- Startup: without admin groups, the warning also names what nobody can do in the mode of service types (#248, #251)
Documentation¶
- Upgrade steps from 0.4.0, and the deviations from the GA4GH specification on the API page (#248, #251)
- Deployment: don't deploy moving image tags (
latest,dev) in production, and check the kernel of the nodes before running MongoDB 8.0 (#222, #223) - The release version comes from one source (
CITATION.cff), so that the docs and the chart's README show the current release (#220, #224) - The Zenodo DOI, and badges in the README (#177, #231; #229, #230, #232)
Maintenance¶
- Workflows and jobs follow the names of all FOCA apps (
ci.yml,release.yml,scan.yml), with a single required check,CI passed. Releases are signed byrelease.ymlnow: see "Verifying images and charts" on the Operations page of the documentation (#233, #234) - Curated release notes are required for every release, and Sourcery skips the inputs of rule tests (#248, #251; #227, #228)