Background
Fedify already documents several important security considerations, but the
guidance is distributed across multiple manual chapters.
For example:
- the deployment guide discusses
sanitizing federated HTML, Content Security Policy, SSRF prevention, secret
management, worker isolation, and production hardening;
- the access control guide
explains authorized fetch and application-level authorization;
- the vocabulary guide describes Fedify's
origin-based security model;
- the message queue guide covers background
processing and queue backends; and
- the integration guide explains how
Fedify and application routes can share the same HTTP service.
Because these responsibilities are documented alongside individual features,
there is no single manual chapter that presents the overall threat model of a
Fedify application, explains which protections Fedify provides, and identifies
which security boundaries remain the application's responsibility.
This can be especially difficult for developers who are new to ActivityPub or
distributed deployments. It is also easy for generated code or coding agents
to produce an implementation that works functionally while missing an
application-level trust boundary.
For example, applications may separate public HTTP handling from queue and
background processing. A background worker may later need to communicate with
a web or stateful component to broadcast streaming updates, deliver
notifications, invalidate caches, or invoke another application-specific
operation.
A tempting implementation is to expose an HTTP endpoint under a path such as
/internal/* and call it from the background worker. However, an internal
path name does not establish an access-control boundary. If the endpoint is
registered on the same router or service that handles public traffic, it may
also be reachable from the public internet.
Similarly, CORS is a browser policy rather than a service authentication
mechanism. Non-browser clients can call such endpoints directly.
These concerns are not specific to one runtime or deployment platform. Similar
trust boundaries exist when using separate processes, containers, Kubernetes
services, queue consumers, or serverless platforms.
Proposal
Add a dedicated application security chapter to the Fedify manual.
Rather than duplicating every existing document, the chapter could provide a
central threat-model and shared-responsibility overview, summarize the
important security invariants, and link to the existing detailed
documentation.
A possible outline follows.
Fedify's security boundary
- Explain which protocol-level protections Fedify provides.
- Identify which data must still be treated as untrusted.
- Clarify that a valid HTTP signature authenticates a key or actor but does not
guarantee that the sender is benign or that supplied content is safe.
- Explain which validation, authorization, rendering, and deployment decisions
remain application responsibilities.
- Distinguish Fedify's built-in protections from protections that must be
implemented by the surrounding application.
Federated input and content rendering
- Validate ActivityPub objects and application-specific fields before use.
- Sanitize federated HTML before rendering it in a browser.
- Apply output encoding appropriate to each rendering context.
- Avoid treating content as trusted solely because it came from a signed
activity, queue, or internal service.
- Use Content Security Policy as defense in depth rather than as a replacement
for sanitization.
Remote resource fetching and SSRF
- Use Fedify's protected document loaders where possible.
- Apply equivalent URL validation to application-managed fetches.
- Validate redirect targets rather than validating only the initial URL.
- Avoid production use of development-oriented security bypasses such as
allowPrivateAddress.
- Document which application-level fetches are not covered by Fedify's built-in
protections.
Authentication and authorization
- Distinguish HTTP signature verification from application authorization.
- Explain authorized fetch and when it may be appropriate.
- Apply explicit authorization to application-defined API, administrative, and
maintenance operations.
- Avoid relying on path names, request origin assumptions, or CORS as access
controls.
- Prefer deny-by-default behavior for privileged operations.
Web and background-processing boundaries
- Keep background workers and internal application handlers outside public
ingress.
- Avoid using unauthenticated public HTTP routes for internal operations.
- Prefer queue-native processing or capability-scoped private transports.
- Validate queue and RPC payloads at the receiving boundary, including
allowlisting supported operations and targets.
- Avoid treating messages as trusted solely because they arrived through an
internal queue, RPC interface, or private network.
- Define clear ownership for application control operations so that they are
not accidentally registered on a public router.
When HTTP cannot be avoided, the guide could recommend:
- authenticating the calling service;
- verifying request integrity;
- limiting the caller's authority;
- including freshness information such as timestamps;
- preventing replay with nonces or equivalent mechanisms; and
- failing closed when authentication or validation cannot be completed.
Secrets and cryptographic keys
- Distinguish instance-wide secrets from per-actor signing keys.
- Explain recommended storage, backup, and rotation practices.
- Avoid secrets in source control, logs, public Worker configuration, or queue
payloads.
- Minimize which components receive each secret or privileged binding.
- Consider deployment-specific secret managers where available.
Platform-specific guidance
The guide could keep its core security invariants platform-independent while
also documenting stronger implementation patterns available in particular
deployment environments.
Examples could include:
- Cloudflare Workers Service Bindings and named
WorkerEntrypoint RPC
interfaces for capability-scoped communication between Workers;
- Cloudflare Queue handlers for background processing without introducing
additional public HTTP endpoints;
- Kubernetes
ClusterIP services combined with NetworkPolicies, workload
identities, or service-mesh mTLS;
- loopback interfaces or private container networks for separately deployed
web and worker processes;
- private service integrations offered by other serverless platforms;
- authenticated message brokers or dedicated queues for background work; and
- platform-specific secret stores and workload identity mechanisms.
These sections would make the guidance actionable without presenting one
platform's solution as a universal requirement.
Each platform-specific section could describe:
- the preferred security mechanism;
- which trust boundary it establishes;
- important limitations and residual risks;
- fallback approaches when the preferred mechanism is unavailable;
- recommended deployment configuration; and
- positive and negative tests that verify the boundary.
A central application security chapter would provide a natural place to
collect and link these recommendations as support for additional runtimes and
deployment platforms is added to Fedify.
Documentation and contribution structure
The documentation should distinguish between platform-independent security
guidance and environment-specific implementation guidance.
This distinction would allow users who operate Fedify in different
environments to contribute practical solutions without requiring every
platform detail to be added to the central security chapter.
General security guidance
The central application security chapter should contain guidance that applies
regardless of runtime, hosting provider, framework, or orchestration system.
Examples include:
- the overall Fedify application threat model;
- the distinction between authentication and authorization;
- treating federated and remotely supplied data as untrusted;
- sanitizing content before rendering;
- preventing SSRF in application-managed fetches;
- keeping privileged operations outside public ingress;
- validating queue, RPC, and internal service payloads;
- avoiding path names or CORS as access controls;
- applying least privilege to services, credentials, and bindings; and
- testing both successful operations and rejected public access.
The general chapter should describe the security property that an application
needs to preserve without requiring one platform-specific implementation.
Environment-specific guidance
Guidance that depends on a particular runtime, hosting provider, network
model, queue implementation, or platform capability should be documented in a
separate environment-specific document.
Examples include:
- Cloudflare Workers Service Bindings, named
WorkerEntrypoint RPC methods,
Worker routes, and Cloudflare Queue behavior;
- Kubernetes Services, NetworkPolicies, workload identities, ingress
configuration, and service-mesh mTLS;
- container network configuration and loopback-only worker processes;
- serverless platform private service integrations;
- provider-specific secret stores and identity mechanisms; and
- environment-specific WAF, proxy, routing, or queue behavior.
Environment-specific documents could also describe security problems that are
unique to, or especially easy to introduce in, that environment.
Each document should identify:
- the environment and supported versions;
- the security boundary being protected;
- common insecure implementation patterns;
- the recommended platform-native solution;
- alternative solutions when the preferred mechanism is unavailable;
- configuration or code examples;
- deployment and regression tests;
- important limitations and residual risks; and
- links back to the relevant general security invariants.
Deciding where guidance belongs
A contribution could use the following decision process:
- If the risk and recommendation apply regardless of deployment environment,
add them to the general application security chapter.
- If the recommendation depends on a platform-specific API, configuration,
network model, or security feature, add a separate environment-specific
document.
- If a problem has both general and platform-specific aspects, document the
common risk and invariant in the general chapter, then document each
concrete implementation in the relevant environment-specific documents.
- Avoid repeating the full general security explanation in each platform
document. Link back to the central chapter instead.
- Update the central platform index when adding a new environment-specific
document.
For example, the general guide could state that privileged communication
between web and background-processing components must not be exposed through
unauthenticated public HTTP routes.
A Cloudflare-specific document could then explain how to preserve that
invariant using Service Bindings and named WorkerEntrypoint RPC methods. A
Kubernetes-specific document could explain the same invariant using internal
Services, NetworkPolicies, workload identities, or mTLS.
Suggested document layout
One possible layout is:
docs/secure-coding/index.md
docs/secure-coding/cloudflare-workers.md
docs/secure-coding/containers.md
docs/secure-coding/kubernetes.md
docs/secure-coding/serverless.md
Deployment verification
The guide could include tests and checks that operators can perform before
deployment.
Examples include:
- confirm that worker-only components are not reachable through public
ingress;
- verify that internal operations cannot be invoked through the public
application origin;
- test authorization failure paths in addition to successful internal calls;
- verify that public requests to reserved internal paths return
404 or
another non-successful response;
- confirm that queue and RPC receivers reject unsupported operations or
malformed payloads;
- confirm that production configuration does not enable development-only
security bypasses;
- verify that secrets and privileged bindings are provided only to components
that require them; and
- run a concise pre-deployment application security checklist.
Suggested implementation
The initial change could remain documentation-only:
- add a new manual chapter such as
docs/manual/security.md;
- link it from the manual navigation and relevant feature chapters;
- consolidate or summarize general security guidance currently located in
the deployment guide;
- retain detailed feature-specific guidance in its existing chapters while
linking back to the central security guide;
- define the shared application security model and trust boundaries in the
central chapter;
- add platform-specific subsections or linked examples for security
mechanisms available only in particular environments; and
- add a concise application security checklist.
The central chapter would define the common security invariants. Individual
runtime, integration, queue, and deployment chapters could then document the
strongest practical way to preserve those invariants in each supported
environment.
This structure would also make it easier to add new platform-specific guidance
later without reducing the general security model to a lowest-common-
denominator set of recommendations.
Follow-up changes could add or update working examples, such as:
- a Cloudflare multi-Worker example using a named Service Binding entrypoint;
- a regression test confirming that the same operation is unavailable through
the public Worker origin;
- a container example in which only the web process binds a public port; or
- a Kubernetes example showing separate public and worker workloads.
Generated project documentation or coding-agent instructions could eventually
include the same invariants so that new applications begin with safer
defaults.
Scope
This proposal is about documenting application-level security responsibilities
and trust boundaries.
It does not suggest that Fedify's current protocol implementation is
vulnerable, and it does not initially require a new public API.
The primary goal is to make existing protections and application
responsibilities easier to discover and to provide a structure for documenting
secure, environment-specific implementation patterns.
AI usage disclosure
This issue draft was mainly assisted-by chatgpt codex:gpt-5-6-sol, and fully reviewed by human, and some fixed.
Fix history
- As per /docs/manual/ folders are for manual about fedify, changed possible layout folder to /docs/secure-coding/
Background
Fedify already documents several important security considerations, but the
guidance is distributed across multiple manual chapters.
For example:
sanitizing federated HTML, Content Security Policy, SSRF prevention, secret
management, worker isolation, and production hardening;
explains authorized fetch and application-level authorization;
origin-based security model;
processing and queue backends; and
Fedify and application routes can share the same HTTP service.
Because these responsibilities are documented alongside individual features,
there is no single manual chapter that presents the overall threat model of a
Fedify application, explains which protections Fedify provides, and identifies
which security boundaries remain the application's responsibility.
This can be especially difficult for developers who are new to ActivityPub or
distributed deployments. It is also easy for generated code or coding agents
to produce an implementation that works functionally while missing an
application-level trust boundary.
For example, applications may separate public HTTP handling from queue and
background processing. A background worker may later need to communicate with
a web or stateful component to broadcast streaming updates, deliver
notifications, invalidate caches, or invoke another application-specific
operation.
A tempting implementation is to expose an HTTP endpoint under a path such as
/internal/*and call it from the background worker. However, aninternalpath name does not establish an access-control boundary. If the endpoint is
registered on the same router or service that handles public traffic, it may
also be reachable from the public internet.
Similarly, CORS is a browser policy rather than a service authentication
mechanism. Non-browser clients can call such endpoints directly.
These concerns are not specific to one runtime or deployment platform. Similar
trust boundaries exist when using separate processes, containers, Kubernetes
services, queue consumers, or serverless platforms.
Proposal
Add a dedicated application security chapter to the Fedify manual.
Rather than duplicating every existing document, the chapter could provide a
central threat-model and shared-responsibility overview, summarize the
important security invariants, and link to the existing detailed
documentation.
A possible outline follows.
Fedify's security boundary
guarantee that the sender is benign or that supplied content is safe.
remain application responsibilities.
implemented by the surrounding application.
Federated input and content rendering
activity, queue, or internal service.
for sanitization.
Remote resource fetching and SSRF
allowPrivateAddress.protections.
Authentication and authorization
maintenance operations.
controls.
Web and background-processing boundaries
ingress.
allowlisting supported operations and targets.
internal queue, RPC interface, or private network.
not accidentally registered on a public router.
When HTTP cannot be avoided, the guide could recommend:
Secrets and cryptographic keys
payloads.
Platform-specific guidance
The guide could keep its core security invariants platform-independent while
also documenting stronger implementation patterns available in particular
deployment environments.
Examples could include:
WorkerEntrypointRPCinterfaces for capability-scoped communication between Workers;
additional public HTTP endpoints;
ClusterIPservices combined with NetworkPolicies, workloadidentities, or service-mesh mTLS;
web and worker processes;
These sections would make the guidance actionable without presenting one
platform's solution as a universal requirement.
Each platform-specific section could describe:
A central application security chapter would provide a natural place to
collect and link these recommendations as support for additional runtimes and
deployment platforms is added to Fedify.
Documentation and contribution structure
The documentation should distinguish between platform-independent security
guidance and environment-specific implementation guidance.
This distinction would allow users who operate Fedify in different
environments to contribute practical solutions without requiring every
platform detail to be added to the central security chapter.
General security guidance
The central application security chapter should contain guidance that applies
regardless of runtime, hosting provider, framework, or orchestration system.
Examples include:
The general chapter should describe the security property that an application
needs to preserve without requiring one platform-specific implementation.
Environment-specific guidance
Guidance that depends on a particular runtime, hosting provider, network
model, queue implementation, or platform capability should be documented in a
separate environment-specific document.
Examples include:
WorkerEntrypointRPC methods,Worker routes, and Cloudflare Queue behavior;
configuration, and service-mesh mTLS;
Environment-specific documents could also describe security problems that are
unique to, or especially easy to introduce in, that environment.
Each document should identify:
Deciding where guidance belongs
A contribution could use the following decision process:
add them to the general application security chapter.
network model, or security feature, add a separate environment-specific
document.
common risk and invariant in the general chapter, then document each
concrete implementation in the relevant environment-specific documents.
document. Link back to the central chapter instead.
document.
For example, the general guide could state that privileged communication
between web and background-processing components must not be exposed through
unauthenticated public HTTP routes.
A Cloudflare-specific document could then explain how to preserve that
invariant using Service Bindings and named
WorkerEntrypointRPC methods. AKubernetes-specific document could explain the same invariant using internal
Services, NetworkPolicies, workload identities, or mTLS.
Suggested document layout
One possible layout is:
Deployment verification
The guide could include tests and checks that operators can perform before
deployment.
Examples include:
ingress;
application origin;
404oranother non-successful response;
malformed payloads;
security bypasses;
that require them; and
Suggested implementation
The initial change could remain documentation-only:
docs/manual/security.md;the deployment guide;
linking back to the central security guide;
central chapter;
mechanisms available only in particular environments; and
The central chapter would define the common security invariants. Individual
runtime, integration, queue, and deployment chapters could then document the
strongest practical way to preserve those invariants in each supported
environment.
This structure would also make it easier to add new platform-specific guidance
later without reducing the general security model to a lowest-common-
denominator set of recommendations.
Follow-up changes could add or update working examples, such as:
the public Worker origin;
Generated project documentation or coding-agent instructions could eventually
include the same invariants so that new applications begin with safer
defaults.
Scope
This proposal is about documenting application-level security responsibilities
and trust boundaries.
It does not suggest that Fedify's current protocol implementation is
vulnerable, and it does not initially require a new public API.
The primary goal is to make existing protections and application
responsibilities easier to discover and to provide a structure for documenting
secure, environment-specific implementation patterns.
AI usage disclosure
This issue draft was mainly assisted-by chatgpt codex:gpt-5-6-sol, and fully reviewed by human, and some fixed.
Fix history