Repository navigation
v0.21.0
Pre-release
Pre-release
·
38 commits
to dev
since this release
Immutable
release. Only release title and notes can be modified.
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.backendis now aSecretStr, as are thedb.client_optionsauthMechanismPropertiesandtlsCertificateKeyFilePassword, 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, aValueError; otherOperationFailures 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
logsection 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
400for values that don't fit the formatsdate-time,dateoruri, for unpaired surrogates in JSON and, withstrict_validation, for query parameters of operations without parameters; withvalidate_responses, the same format checks answer500, also for stored data (#617, #686) is_admin()isFalsefor models with global and resource-scoped roles whose matcher doesn't start with exactlyg(r.sub, "admin") ||(#613, #682)- Gateway plugins:
request_id()followsserver.request_idinstead of taking any client'sX-Request-ID, so that by default the fieldrequest_idof 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 argumentPY_IMAGEonly takes3.11to3.15with-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 formatterjsonwrites one JSON object per line, andlogtakes filters, loggers and more options (#620, #684) - The console script
foca, withcheck-config,create-indexes,sync-policiesandexport-spec, and the switchesdb.create_indexes_on_startupandsecurity.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 logsPolicy rule '...' added.,updated.ordeleted.on its own logger (#614, #689) foca.testing: a local OIDC issuer and a pytest plugin with a network guard and amongodbfixture, with the extrafoca[testing](#630, #679)GET /me, off by default, with a hook for fields of the app (#610, #687)- Access control:
api_enabledandapi_base_pathof the permissions API (#611, #678);required_roles,require_enforced, packaged models withmodel: foca:<file>andresource_roles_cover_custom_methods(#613, #682);is_permitted_for(),get_api_base_path(),get_resource_path()and{base_path}in policies (#606, #667) getResourceRolesofownership_servertakesq,limitandoffset(#609, #681)foca.utils.pagination,IdConfigfor identifiers andservice_info.locked_fields(#623, #676)db.client_optionsfor 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.periodicfor the schedules of Celery beat, and hints for configuration keys removed in 0.14 (#622, #688)foca.gunicorn_configbinds to the port inPORT, by default 8080 (#619, #662)- Startup warnings for a service info with the placeholder version
0.0.0.dev0and for gateways without loop detection (#624, #664) - The release has
foca-image-requirements-py<version>.txtas assets, to install the same versions in images built on the FOCA image (#629, #685) - foca-common 0.5.0:
extraEnv,extraEnvFromandrolloutOnSecrets(#626, #672); autoscaling and topology spread constraints (#627, #677); gateway apps withplugins,backendsKeyandrequireAccessControl, and Flower (#628, #692)
Security
- By default, apps generate the request's identifier and ignore what clients send;
server.request_id.trust_incomingis 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, answers401for 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.exceptionslogs 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 ofservice_idinGET /verifications, so that apps such as proTES no longer end up without backends;groupandartifactignore surrounding whitespace (#665, #670) - Revocations in
GET /verificationsapply to cached backends even ifGET /servicesfails (#673, #683) - Older pods no longer overwrite the configured rules of newer ones during rolling upgrades, with
policies_revisionandpolicies_force(#612, #680) - Admins can list the roles of resources without owners and assign their first owner, if the operation of
ownership_serveris passed an existence check (#608, #666)
Documentation
- The migration guide covers all changes of behaviour, and the docs explain
PORTand the limits of thefocacommand (#693, #694) - Links to the docs of Casbin, and a contributing note on upgrading system packages of the image (#697, #698; #699, #700)
NOTICEhas 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