graphql-federation — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited graphql-federation (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Create correct GraphQL federation subgraphs following WunderGraph Cosmo composition rules.
Subgraph: A GraphQL microservice contributing to the federated graph. Federated Graph/Supergraph: The composed GraphQL interface for clients. Router: Plans operations, routes requests to subgraphs, joins data. Entity: A type with @key directive resolvable across subgraphs. Router Schema vs Client Schema: Router sees all fields; clients don't see @inaccessible items.
# Basic entity
type User @key(fields: "id") {
id: ID!
name: String!
}
# Multiple keys
type Product @key(fields: "id") @key(fields: "sku") {
id: ID!
sku: String!
name: String!
}
# Composite key
type Review @key(fields: "author { id } product { id }") {
author: User!
product: Product!
rating: Int!
}
# Non-resolvable key (reference only, can't resolve this entity)
type User @key(fields: "id", resolvable: false) {
id: ID!
}Key Rules:
# When same field exists in multiple subgraphs
type User @key(fields: "id") {
id: ID!
name: String! @shareable # Can be defined in other subgraphs
}
# Object-level shareable applies to all fields
type User @key(fields: "id") @shareable {
id: ID!
name: String!
email: String!
}Shareable Rules:
# Mark fields resolved by another subgraph
extend type User @key(fields: "id") {
id: ID! @external
name: String! @external
reviews: [Review!]! # This subgraph resolves reviews
}External Rules:
type Product @key(fields: "id") {
id: ID!
price: Float! @external
currency: String! @external
formattedPrice: String! @requires(fields: "price currency")
}Requires Rules:
@requires(fields: "details { weight }")type Query {
topProducts: [Product!]! @provides(fields: "name description")
}
type Product @key(fields: "id") {
id: ID!
name: String! @external
description: String! @external
}Provides Rules:
# In new subgraph, taking over from "old-service"
type User @key(fields: "id") {
id: ID!
name: String! @override(from: "old-service")
}Override Rules:
type User @key(fields: "id") {
id: ID!
name: String!
internalId: String! @inaccessible # Hidden from clients
}
# Entire type can be inaccessible
type InternalMetrics @inaccessible {
requestCount: Int!
}Inaccessible Rules:
# Subgraph A defines the interface
interface Media @key(fields: "id") {
id: ID!
title: String!
}
type Book implements Media @key(fields: "id") {
id: ID!
title: String!
author: String!
}
# Subgraph B adds fields to ALL implementations
type Media @key(fields: "id") @interfaceObject {
id: ID!
reviews: [Review!]! # Added to Book and all Media types
}InterfaceObject Rules:
type Query {
publicData: String!
privateData: String! @authenticated
adminData: String! @requiresScopes(scopes: [["admin"], ["superuser"]])
}
# Type-level auth
type SecretDocument @authenticated @requiresScopes(scopes: [["read:secrets"]]) {
content: String!
}# Subgraph A - owns User
type User @key(fields: "id") {
id: ID!
name: String!
email: String!
}
# Subgraph B - extends User with posts
extend type User @key(fields: "id") {
id: ID! @external
posts: [Post!]!
}
type Post @key(fields: "id") {
id: ID!
title: String!
author: User!
}type Mutation {
createUser(input: CreateUserInput!): User!
}
# Entity returned from mutation allows field resolution from other subgraphs
type User @key(fields: "id") {
id: ID!
name: String!
}interface Node @key(fields: "id") {
id: ID!
}
type User implements Node @key(fields: "id") {
id: ID!
name: String!
}
type Product implements Node @key(fields: "id") {
id: ID!
title: String!
}# ERROR: Field defined in multiple subgraphs without @shareable
# Subgraph A
type User @key(fields: "id") {
id: ID!
name: String! # Missing @shareable
}
# Subgraph B
type User @key(fields: "id") {
id: ID!
name: String! # Conflict!
}
# FIX: Add @shareable to both
type User @key(fields: "id") {
id: ID!
name: String! @shareable
}# ERROR: Field cannot be resolved from Query entry point
# Subgraph A
type Query {
user: User! # Only in A
}
type User {
id: ID!
name: String! # Only in A
}
# Subgraph B
type User {
email: String! # Only in B, but User has no @key!
}
# FIX: Add @key to make User an entity
type User @key(fields: "id") {
id: ID!
name: String!
}# ERROR: @requires on non-external field
type Product @key(fields: "id") {
id: ID!
price: Float! # Missing @external
formattedPrice: String! @requires(fields: "price")
}
# FIX: Mark as external
type Product @key(fields: "id") {
id: ID!
price: Float! @external
formattedPrice: String! @requires(fields: "price")
}For detailed directive specifications, see:
references/directives.md - Complete directive documentationreferences/composition-rules.md - Composition validation rulesreferences/patterns.md - Advanced federation patterns~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.