Skip to content

fix(composition): restrict usage of auth directives on interfaces#8826

Merged
dariuszkuc merged 5 commits intodevfrom
restrict_auth_on_interfaces
Feb 2, 2026
Merged

fix(composition): restrict usage of auth directives on interfaces#8826
dariuszkuc merged 5 commits intodevfrom
restrict_auth_on_interfaces

Conversation

@dariuszkuc
Copy link
Copy Markdown
Member

Restricts usage of @authenticated, @policy and @requiresScopes from being applied on interfaces, interface objects and their fields.

GraphQL spec currently does not define any interface inheritance rules and developers have to explicitly redefine all interface fields on their implementations. At runtime, GraphQL servers cannot return abstract types and always return concrete output types. Due to the above, applying auth directives on the interfaces may lead to unexpected runtime behavior as they won't have any effect at runtime.

Backport of apollographql/federation@faea2d1

@dariuszkuc dariuszkuc requested a review from a team January 22, 2026 18:04
@dariuszkuc dariuszkuc requested review from a team as code owners January 22, 2026 18:04
@apollo-librarian
Copy link
Copy Markdown
Contributor

apollo-librarian bot commented Jan 22, 2026

✅ Docs preview has no changes

The preview was not built because there were no changes.

Build ID: afaf59e8ce9704c4aac96c9a
Build Logs: View logs

self.directives.get(name).ok_or_else(|| {
internal_error!("Directive referencers unexpectedly missing directive `{name}`")
})
pub(crate) fn get_directive(&self, name: &str) -> &DirectiveReferencers {
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In Federation JS we generally use safe getPost20FederationDirective (link) that returns empty applications (aka referencers in RS) if not found. By changing this to return empty referencers we can avoid a number of potential exceptions when directive would be defined in the schema but not applied anywhere.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a big fan of removing as many unnecessary "failure" cases as possible.

@dariuszkuc dariuszkuc requested a review from duckki January 23, 2026 23:08
@sachindshinde sachindshinde self-requested a review January 26, 2026 20:49
self.directives.get(name).ok_or_else(|| {
internal_error!("Directive referencers unexpectedly missing directive `{name}`")
})
pub(crate) fn get_directive(&self, name: &str) -> &DirectiveReferencers {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a big fan of removing as many unnecessary "failure" cases as possible.

}
};
.get_directive(JOIN_DIRECTIVE);
if join_directives.len() == 0 {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit, but a lint that I'm surprised clippy isn't complaining about: This should be an is_empty call.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's because we're using a len() that we wrote/it's not a standard collection.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah its a custom len() method -> I've added new is_empty() and updated code accordingly

Base automatically changed from dnf_conjunction to dev January 30, 2026 22:51
Restricts usage of `@authenticated`, `@policy` and `@requiresScopes` from being applied on interfaces, interface objects and their fields.

GraphQL spec currently does not define any interface inheritance rules and developers have to explicitly redefine all interface fields on their implementations. At runtime, GraphQL servers cannot return abstract types and always return concrete output types. Due to the above, applying auth directives on the interfaces may lead to unexpected runtime behavior as they won't have any effect at runtime.

Backport of apollographql/federation@faea2d1
@dariuszkuc dariuszkuc force-pushed the restrict_auth_on_interfaces branch from 36805d3 to bf63d5b Compare January 30, 2026 23:22
@github-actions
Copy link
Copy Markdown
Contributor

@dariuszkuc, please consider creating a changeset entry in /.changesets/. These instructions describe the process and tooling.

@dariuszkuc dariuszkuc enabled auto-merge (squash) January 30, 2026 23:23
@hwillson hwillson self-requested a review February 2, 2026 12:25
Comment thread apollo-federation/src/schema/validators/access_control.rs
@dariuszkuc dariuszkuc merged commit 69a3c7d into dev Feb 2, 2026
15 checks passed
@dariuszkuc dariuszkuc deleted the restrict_auth_on_interfaces branch February 2, 2026 17:04
the-gigi-apollo pushed a commit that referenced this pull request Feb 4, 2026
)

Restricts usage of `@authenticated`, `@policy` and `@requiresScopes` from being applied on interfaces, interface objects and their fields.

GraphQL spec currently does not define any interface inheritance rules and developers have to explicitly redefine all interface fields on their implementations. At runtime, GraphQL servers cannot return abstract types and always return concrete output types. Due to the above, applying auth directives on the interfaces may lead to unexpected runtime behavior as they won't have any effect at runtime.

Backport of apollographql/federation@faea2d1
briannafugate408 pushed a commit that referenced this pull request Feb 4, 2026
)

Restricts usage of `@authenticated`, `@policy` and `@requiresScopes` from being applied on interfaces, interface objects and their fields.

GraphQL spec currently does not define any interface inheritance rules and developers have to explicitly redefine all interface fields on their implementations. At runtime, GraphQL servers cannot return abstract types and always return concrete output types. Due to the above, applying auth directives on the interfaces may lead to unexpected runtime behavior as they won't have any effect at runtime.

Backport of apollographql/federation@faea2d1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants