1.35.0 — CloudFront delivery for S3 files, sites own their Permissions-Policy, one Setting row per key
Editorial identity incomplete
2026-10-14
Private and public S3 files can now be served through CloudFront, provisioned by django-mojo under the deployment's AWS identity or brought as your own distribution, with signed links for private managers. The edge no longer sends a Permissions-Policy header; a site that wants one sets it itself. Platform-wide Setting keys are unique with a repairing migration, and a File's storage and stored object are server-controlled on REST writes.
Breaking
- The edge no longer sends
Permissions-Policy. Camera, microphone, geolocation and media access are the site's decision; a site that relied on the platform denying them must set the header itself. - A REST create or save of a File ignores the manager, owner, stored path and name, upload token and state, link, size, checksum and category. Storage is chosen by the server: the upload rule for user sessions, and for an API key or group token only group storage its permissions allow.
Added
- CDN delivery for S3 file managers:
CdnDistribution(one per bucket) andCdnSigningKeymodels, thefileman_cdncommand (enable, check, byo, disable, rotate-key, revoke-key) and the FileManager actionsenable_cdn,check_cdn,disable_cdn. - Provisioning converges additively under the deployment's AWS identity: origin access control, key group, distribution, bucket and KMS policies. A second run creates nothing; nothing is ever deleted; an untagged distribution on the same bucket is reported, never adopted.
- Public managers get unsigned CDN links that never expire; private managers get signed links, default 7 days, capped by
FILEMAN_CDN_MAX_EXPIRES_IN(default 90 days). Manager settingscdn(offopts a manager out) andcdn_url_expires_in. - The manager graph carries a read-only
cdnobject with the address, signed or public, and deployment status. - CloudFront invalidation when a rendition is regenerated or a file deleted; a daily job retires rotated signing keys once their links have expired.
- A bring-your-own distribution can be registered and validated with exact remediation for each finding.
- MojoSec per-receipt events (web probes, file-integrity changes) age out after
MOJOSEC_RECEIPT_RETENTION_DAYS, with a count-first preview command.
Changed
- The CDN actions and settings require the global
manage_filesorfilespermission; the group-level grant that lets someone edit a manager does not drive the deployment's AWS identity. - On a CDN bucket, a private manager under a public prefix is refused, and so is a prefix containing
*or?: the edge could not protect it. - Making a CDN manager private converges the edge before the save and refuses the save if CloudFront refuses.
- A group manager cannot make an API key act as another member.
- Short-link docs: the admin preset is not a wildcard;
manage_shortlinksis granted by name.
Fixed
- Platform-wide Setting keys are unique; a duplicate create or a rename onto a taken key returns 400 in both scopes instead of a 500 or an arbitrary winner.
Setting.savewith an emptyupdate_fieldswrites and publishes nothing, and binds a positionalupdate_fieldsthe way Django does.- A nested save on a missing reverse one-to-one returns 400, not 500.
- MojoSec event pruning locks each batch, so an Incident linked mid-prune keeps its Event.
- testit: a refused launch never leaves an older report looking current; a raising setup function is a counted error that stops its file; a run that ran nothing fails.
Upgrade notes
- Migration
account.0055makes platform-wide Setting keys unique. Where a key has several rows it keeps the oldest and deletes the others, logging the key and row ids (never values), and holds settings writers off while it runs. A Redis failure during its cache clear is reported and never fails the migration. - Migration
fileman.0017adds the two CDN tables. Nothing changes for existing managers until a bucket's CDN is enabled. - CDN provisioning stores signing keys in the KMS envelope, so
KMS_KEY_IDmust be set on a deployment that enables it. A bucket on theaws/s3managed key is reported as manual: that key's policy cannot grant CloudFront, use a dedicated CMK. - The Permissions-Policy change applies to every edge-served page on upgrade. Sites that want the old deny behavior add the header in their own responses.