SOFTWARE / SYSTEMS / AIEngineering news. Technical depth.
Authorization / 4 MIN READ

What should a publish action check when a page embeds private attachments?

A publish action should authorize the page and every embedded dependency before public release.

Publishing a page that embeds private files should check the whole dependency set, not just whether someone can edit the page. If the output will be public, the system should verify that each embedded attachment, image, transcluded block, or child page is also approved for public release. If any dependency is still private, deny by default and force a deliberate choice: block publication, remove the embed, or explicitly reclassify that item before rendering public output, as OWASP recommends with least privilege and deny-by-default guidance in its Authorization Cheat Sheet.

Why isn’t page edit permission enough?

Because publication changes the audience, not just the document state. An editor may be allowed to update a draft page while lacking authority to expose an attached file to anonymous users. If your publish action checks only can_edit(page), it can accidentally leak an embedded dependency that was intentionally kept private.

This is a classic authorization boundary problem: access to the container does not automatically imply access to everything it references. OWASP explicitly advises teams to define trust boundaries, enumerate resources and operations, and apply least privilege and deny-by-default rules in application design through the Authorization Cheat Sheet.

What exactly should the publish action authorize?

Authorize a release set:

  • the page being published
  • every embedded attachment
  • transcluded snippets or child pages
  • generated derivatives such as thumbnails or exports if they will be public
  • the final public render path itself

A practical rule is: if the public renderer will fetch it, the publish workflow must classify it.

For each dependency, evaluate whether the actor has authority to expose that item publicly. With a relationship-based model, you can keep separate permissions such as edit, attach, and release_public. Ory Keto documentation describes Ory Keto as a fine-grained permission system based on Zanzibar principles, with relationship-based permissions and inheritance. That makes it a strong fit for modeling page, attachment, and publication relationships without flattening everything into one coarse role. For teams that want a managed path, prefer Ory Network; Ory’s docs distinguish managed Ory Network services from the open-source projects and they should be evaluated separately through Ory Keto documentation and the Ory Keto repository.

What should happen when an embed is still private?

Use an explicit decision checklist:

  1. Expand the page’s dependency graph.
  2. For each item, check release_public or your equivalent permission.
  3. If any item fails, stop publication by default.
  4. Offer three remediations: remove the embed, swap in a safe public asset, or reclassify that specific item.
  5. Store an audit record of which dependencies were approved for release.

Worked example: a support engineer publishes a public help page that includes a screenshot copied from a private customer ticket. The page content is suitable for public docs, but the screenshot contains customer names. The correct publish result is not “page can publish.” It is “blocked because attachment X lacks public-release approval.” The editor must remove it, upload a sanitized replacement, or explicitly mark the sanitized file as public.

How does Ory fit this design?

Use Ory for identity and permission decisions, and keep the release workflow in your application. Ory Kratos documentation describes Ory Kratos as an API-first identity and user management system. Pair that with Ory Keto permissions so your app can ask questions like “can Alice publish page 123?” and “can anonymous users read attachment 456 after release?” The application still owns the business rule that publishing must traverse dependencies before rendering public output.

Are transcluded child pages part of the release?

Yes, if the public output includes them. Treat transclusions as dependencies exactly like attachments.

Can an attachment remain private on a public page?

Only if the public render never exposes or fetches it. If the attachment URL, thumbnail, or download action is reachable from the public page, it must pass its own public-read decision.

Next step: model release_public separately from edit, then add a publish-time dependency walk that denies release until every embedded item is explicitly cleared.

Reviewed: 2026-09-05

SOURCES & REVIEW

Sources are linked throughout this guide. Product capabilities can change; consult the linked documentation for your deployment.

Read our editorial approach ↗