Subgraph Authentication
Subgraph Authentication allows you to secure communication between the Hive Router and your subgraphs. You can follow this guide to set up how to sign subgraph requests.
By activating this, you can ensure that the requests sent to GraphQL subgraphs are trusted and signed by the Hive Router. In case of any missing signature, tampering or unauthorized access, the subgraph services will reject the request.
HMAC Signature
HMAC (Hash-based Message Authentication Code) is a mechanism for calculating a message authentication code involving a hash function in combination with a secret key. It can be used to verify the integrity and authenticity of a message.
This feature implements HMAC signing for requests between Hive Router and the GraphQL subgraph. It also provides HMAC verification plugin for the incoming requests in the subgraph services.
How to use?
Step 1: Gather your secret key
Before you start, you need to have a secret key that will be used for HMAC signing and verification.
The secret key should be a random, opaque string, that will be shared between the Hive Router and the subgraphs validating the HMAC signature.
Step 2: HMAC Signing in Hive Router
hmac_signature:
enabled: true
secret: 'myHMACSecret' # Use the secret key gathered in step 1Now, every GraphQL request sent to the upstream GraphQL subgraphs will be signed with the HMAC and
the extensions of the upstream request will contain the HMAC signature.
To configure the subgraph verification of the HMAC signature, please follow the next step.
Step 3: HMAC Verification in Subgraph services
The next step is to perform a verification over the sent HMAC signature in the subgraph services:
With GraphQL Yoga
If you are using Yoga, you can use the following package:
npm i @graphql-mesh/hmac-upstream-signatureimport { createYoga } from 'graphql-yoga'
import { useHmacSignatureValidation } from '@graphql-mesh/hmac-upstream-signature'
const myYogaSubgraphServer = createYoga({
// ...
plugins: [
useHmacSignatureValidation({
secret: myHMACSecret // see step 1 for the secret key
})
// other Yoga plugins
// ...
]
})Make sure to add useHmacSignatureValidation first in the plugins list in your Yoga
configuration. This will ensure the request is verified before processing the other plugins.
With Apollo Server
If you are using Apollo-Server for your subgraph services, you can implement a custom plugin to
verify the HMAC signature. You can still use the utilities from the
@graphql-mesh/hmac-upstream-signature library to serialize the request parameters and verify the
HMAC signature in a stable way.
Start by installing the @graphql-mesh/hmac-upstream-signature package:
npm i @graphql-mesh/hmac-upstream-signatureNow, configure your Apollo Server with the HMAC verification plugin:
import { createHmac } from 'crypto'
import { ApolloServer, ApolloServerPlugin } from '@apollo/server'
import { defaultParamsSerializer } from '@graphql-mesh/hmac-upstream-signature'
/* This should be your secret key from Step 1 */
const HMAC_SIGNING_SECRET = 'myHMACSecret' // Use the secret key gathered in step 1
const verifyHmacPlugin = {
async requestDidStart({ request }) {
const signature = request.extensions?.['hmac-signature']
if (!signature) {
throw new Error('HMAC signature is missing')
}
const serializedParams = defaultParamsSerializer({
query: request.query,
variables: request.variables
})
const incomingReqSignature = createHmac('sha256', HMAC_SIGNING_SECRET)
.update(serializedParams)
.digest('base64')
if (incomingReqSignature !== signature) {
throw new Error('HMAC signature is invalid')
}
}
} satisfies ApolloServerPlugin<{}>
const server = new ApolloServer({
plugins: [
verifyHmacPlugin
// ... other Apollo plugins
]
})Other GraphQL servers
To implement HMAC verification in other GraphQL servers, you should implement a HMAC verification using the following specification:
-
The incoming request to your server will contain an
extensionsfield with ahmac-signaturekey. -
The
hmac-signaturevalue is abase64encoded HMAC signature of the request parameters, using the SHA-256 algorithm. -
The request parameters should be serialized in a stable way, so the signature can be verified correctly. It should consist of the GraphQL
queryandvariables:{ "query": "query { comments { id author { id name } } ", "variables": {} } -
The HMAC signature should be calculated using the secret key shared between the Hive Router and the subgraph services.
Here’s an example of an incoming subgraph request with the HMAC signature:
{
"query": "query { comments { id author { id name } } ",
"variables": {},
"extensions": {
"hmac-signature": "AbC123"
}
}The signature is produced by the Hive Router using the shared secret key, and the serialized request (query and variables).
Configuration
Learn more about the options available in the
hmac_signature configuration reference.
AWS Signature Version 4
Hive Router also supports subgraph request authentication and signing using AWS Signature Version 4.
This feature allows you to secure the communication between your router and the AWS-hosted subgraphs by signing requests with AWS credentials so that the subgraphs can verify the authenticity of the requests.
Supported Services
- Amazon S3
- Amazon DynamoDB
- AWS Lambda
- Amazon SQS
- Amazon SNS
- And many more…
Configuration
If you want to learn more about the available configuration options, check the
aws_sig_v4 configuration reference.
Authentication
You have two ways to provide AWS credentials for signing subgraph requests.
Hard-coded Credentials (not recommended)
You can provide AWS credentials directly in the Hive Router configuration file. We do not recommend this approach. See the next section for a more secure way.
aws_sig_v4:
all:
hardcoded:
access_key_id: AKIAIOSFODNN7EXAMPLE
secret_access_key: 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY'
region: us-east-1
service_name: lambdaDefault Chain Authentication (recommended)
The recommended way to provide AWS credentials is to use the Default Chain Authentication method. Hive Router will automatically look for AWS credentials in the following order:
- Environment Variables:
AWS_ACCESS_KEY_IDandAWS_SECRET_ACCESS_KEY - Credential File:
~/.aws/credentials - IAM Roles: For EC2 instances and ECS tasks
- AssumeRole: Via STS AssumeRole operations
- WebIdentity: For Kubernetes service accounts mostly configured via
AWS_WEB_IDENTITY_TOKEN_FILEenvironment variable - SSO: AWS SSO credentials
aws_sig_v4:
all:
default_chain:
profile_name: 'my-test-profile'
region: 'us-east-1'
service_name: 'lambda'
assume_role:
role_arn: 'test-arn'
session_name: 'test-session'Subgraph Specific Configuration
You can also configure AWS Sigv4 signing on a per-subgraph basis. This allows you to have different signing configurations for different subgraphs.
aws_sig_v4:
all:
default_chain:
profile_name: 'my-test-profile'
region: 'us-east-1'
service_name: 'lambda'
assume_role:
role_arn: 'test-arn'
session_name: 'test-session'
subgraphs:
users:
hardcoded:
access_key_id: AKIAIOSFODNN7EXAMPLE
secret_access_key: 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY'
region: eu-west-1
service_name: lambda