Skip to content

v0.21.0

Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 05 Nov 01:08
· 38 commits to dev since this release
Immutable release. Only release title and notes can be modified.
v0.21.0
5eb4f70

FOCA 0.21.0 lets configuration files reference environment variables and takes credentials from files, gives every request an identifier in logs and responses, adds the foca command-line tool, an audit log of changes of access rights and helpers for testing apps, and makes Celery workers safe with MongoDB. Configurations, requests and responses are checked more strictly, so apps may need to change: see the migration guide. Discovery reads serviceId of Cloud Registry 1.0.0rc2. Apps with plugins of foca-plugins can't install this release until foca-plugins allows it.

Breaking changes

  • Configuration files: ${...} now references an environment variable, an unset variable or an invalid form stops the app, and $$ means a literal $; write $$ for each literal $ in these two cases (#625, #691)
  • jobs.backend is now a SecretStr, as are the db.client_options authMechanismProperties and tlsCertificateKeyFilePassword, so code reading them must call .get_secret_value() (#625, #691)
  • Celery workers replace the MongoDB client before starting their pool and in each pool process, so clients, databases and collections kept from earlier raise InvalidOperation (#659, #663)
  • Index conflicts and documents violating a unique index raise IndexConflictError, a ValueError; other OperationFailures when creating indexes stay what they are (#622, #688)
  • Foca.create_celery_app() stops on invalid access control settings, so such a worker doesn't start (#622, #688)
  • A log section naming filters or handlers that it doesn't configure stops the app, instead of falling back to the default logging (#620, #684)
  • Requests can now fail with 400 for values that don't fit the formats date-time, date or uri, for unpaired surrogates in JSON and, with strict_validation, for query parameters of operations without parameters; with validate_responses, the same format checks answer 500, also for stored data (#617, #686)
  • is_admin() is False for models with global and resource-scoped roles whose matcher doesn't start with exactly g(r.sub, "admin") || (#613, #682)
  • Gateway plugins: request_id() follows server.request_id instead of taking any client's X-Request-ID, so that by default the field request_id of pipeline runs and their records has a generated identifier (#620, #684; #695, #696)
  • MongoDB clients time out after 5 seconds when selecting a server and connecting, down from PyMongo's 30 and 20 seconds (#618, #675)
  • docker/Dockerfile: the build argument PY_IMAGE only takes 3.11 to 3.15 with -slim-trixie; images built on the published FOCA images aren't affected (#629, #685)

Features

  • Configuration files reference environment variables with ${VAR}, ${VAR:-default} and ${VAR:?message}, and FOCA's variables with credentials can come from files, with <name>_FILE (#625, #691)
  • Responses have the header X-Request-ID, log records have the request's identifier, operation, subject and client, the formatter json writes one JSON object per line, and log takes filters, loggers and more options (#620, #684)
  • The console script foca, with check-config, create-indexes, sync-policies and export-spec, and the switches db.create_indexes_on_startup and security.access_control.sync_policies_on_startup (#621, #690)
  • Changes of access rights go to the logger foca.audit, with who made them; the permissions API no longer logs Policy rule '...' added., updated. or deleted. on its own logger (#614, #689)
  • foca.testing: a local OIDC issuer and a pytest plugin with a network guard and a mongodb fixture, with the extra foca[testing] (#630, #679)
  • GET /me, off by default, with a hook for fields of the app (#610, #687)
  • Access control: api_enabled and api_base_path of the permissions API (#611, #678); required_roles, require_enforced, packaged models with model: foca:<file> and resource_roles_cover_custom_methods (#613, #682); is_permitted_for(), get_api_base_path(), get_resource_path() and {base_path} in policies (#606, #667)
  • getResourceRoles of ownership_server takes q, limit and offset (#609, #681)
  • foca.utils.pagination, IdConfig for identifiers and service_info.locked_fields (#623, #676)
  • db.client_options for MongoDB clients, which also report a name to MongoDB (appname) (#618, #675)
  • security.auth.userinfo_cache_ttl, for changes of groups read from user info to apply sooner (#615, #669)
  • jobs.periodic for the schedules of Celery beat, and hints for configuration keys removed in 0.14 (#622, #688)
  • foca.gunicorn_config binds to the port in PORT, by default 8080 (#619, #662)
  • Startup warnings for a service info with the placeholder version 0.0.0.dev0 and for gateways without loop detection (#624, #664)
  • The release has foca-image-requirements-py<version>.txt as assets, to install the same versions in images built on the FOCA image (#629, #685)
  • foca-common 0.5.0: extraEnv, extraEnvFrom and rolloutOnSecrets (#626, #672); autoscaling and topology spread constraints (#627, #677); gateway apps with plugins, backendsKey and requireAccessControl, and Flower (#628, #692)

Security

  • By default, apps generate the request's identifier and ignore what clients send; server.request_id.trust_incoming is for apps behind a proxy that replaces or rejects clients' values, as clients could otherwise choose the identifier in logs and audit events (#695, #696)
  • security.auth.reject_invalid_tokens, off by default, answers 401 for invalid tokens on operations with optional authentication, and startup warns of functions it doesn't reach (#607, #668; #693, #694)
  • The repr of database and collection settings no longer shows the credentials of clients, and the log of new MongoDB clients has only hosts and ports as PyMongo understands them, as well as the database (#625, #691)
  • The log no longer has the start of a password containing # (#674, #675)
  • Logs of invalid responses no longer have the response body: Connexion's message is filtered out, and the logger foca.errors.exceptions logs the operation and the error (#616, #671)
  • The FOCA image installs its dependencies with their hashes and pins its base images by digest (#629, #685)
  • The FOCA image upgrades apt for CVE-2026-109518, which its base images don't have the fix of yet (#697, #698)

Fixes

  • MongoDB clients are no longer used across forks in Celery workers (#659, #663)
  • Discovery reads serviceId, which Cloud Registry 1.0.0rc2 has instead of service_id in GET /verifications, so that apps such as proTES no longer end up without backends; group and artifact ignore surrounding whitespace (#665, #670)
  • Revocations in GET /verifications apply to cached backends even if GET /services fails (#673, #683)
  • Older pods no longer overwrite the configured rules of newer ones during rolling upgrades, with policies_revision and policies_force (#612, #680)
  • Admins can list the roles of resources without owners and assign their first owner, if the operation of ownership_server is passed an existence check (#608, #666)

Documentation

  • The migration guide covers all changes of behaviour, and the docs explain PORT and the limits of the foca command (#693, #694)
  • Links to the docs of Casbin, and a contributing note on upgrading system packages of the image (#697, #698; #699, #700)
  • NOTICE has an entry for the Casbin adapter (#655, #657)

Maintenance

  • A real gateway plugin runs in the live service tests (#656, #658)
  • An integration test of the request ID through Gunicorn, and one pinned version of uv in the jobs of CI (#693, #694)
  • Dependency updates (#660, #661)
  • Release preparation for 0.21.0: citation metadata and release notes (#699, #700)

Commits

  • docs: add NOTICE entry for the Casbin adapter by @uniqueg in #657
  • test: run a real gateway plugin in live services by @uniqueg in #658
  • build(deps): Bump astral-sh/uv from 0.13.6 to 0.13.7 in /examples/petstore by @dependabot[bot] in #660
  • feat: read PORT in foca.gunicorn_config by @uniqueg in #662
  • fix: open MongoDB clients after the Celery fork by @uniqueg in #663
  • feat: warn on dev version and loop detection by @uniqueg in #664
  • fix: let admins manage ownerless resources by @uniqueg in #666
  • fix(plugins): read serviceId in discovery by @uniqueg in #670
  • feat: add public path helpers by @uniqueg in #667
  • feat: add option to reject invalid optional tokens by @uniqueg in #668
  • feat(auth): add userinfo_cache_ttl option by @uniqueg in #669
  • fix(errors): log invalid responses without bodies by @uniqueg in #671
  • feat: add id config and pagination helpers by @uniqueg in #676
  • feat(chart): add HPA and topology spread by @uniqueg in #677
  • feat(db): add MongoDB client options by @uniqueg in #675
  • feat(access-control): add API switch, base path by @uniqueg in #678
  • feat(testing): add pytest plugin and test issuer by @uniqueg in #679
  • fix: apply revocations when services can't load by @uniqueg in #683
  • fix(access-control): let newest policies win by @uniqueg in #680
  • feat(access-control): page and filter role lists by @uniqueg in #681
  • feat(access-control): add checks, model options by @uniqueg in #682
  • feat(logging): add request ID and JSON logs by @uniqueg in #684
  • build: pin image deps and base by digest by @uniqueg in #685
  • feat(access-control): add GET /me with app hook by @uniqueg in #687
  • feat(validation): stricter request checks by @uniqueg in #686
  • feat: add worker jobs, index errors, key hints by @uniqueg in #688
  • feat: add audit logger with actor by @uniqueg in #689
  • feat(cli): add foca CLI and startup switches by @uniqueg in #690
  • feat(chart): add gateway helpers by @uniqueg in #692
  • build(deps): Bump astral-sh/uv from 0.13.6 to 0.13.7 in /examples/gateway by @dependabot[bot] in #661
  • fix: address v0.21.0 pre-release findings by @uniqueg in #694
  • fix: don't trust incoming request IDs by default by @uniqueg in #696
  • feat(config)!: support secrets in config by @uniqueg in #691
  • fix(docker): upgrade apt for CVE-2026-109518 by @uniqueg in #698
  • build: prepare the 0.21.0 release by @uniqueg in #700

Full Changelog: v0.20.0...v0.21.0