Documentation
Feedback
Guides
App Development

App Development
App Development
GraphQL authorization in IO apps

Learn to implement and use protected GraphQL operations with IO apps.

Authenticated GraphQL requests are crucial for securing access to your VTEX IO app's data and functions. Authentication ensures that only authorized users or applications can interact with your GraphQL endpoints, protecting sensitive information and preventing unauthorized actions. In addition to authentication, app developers can implement authorization to control who can access specific resources and what operations they can perform.

GraphQL authorization in VTEX IO apps works with auth tokens and directives within your GraphQL schema, enabling fine-grained access control based on License Manager resources. The app identifies the requester by the auth token in apps or the user token in API calls. These tokens have roles or policies associated with VTEX resources.

In this guide, you will learn how to:

  1. Implement protected GraphQL API operations in apps using authorization.
  2. Make authorized requests from apps.
  3. Make external requests with appropriate authorization.

Only VTEX apps, Admin users, and application keys can be authorized to make GraphQL requests, as they must be associated with a role or policy that grants access to a License Manager resource. Store users don't have this type of access.

Implementing GraphQL API authorization in apps

The @auth directive has different implementation methods depending on the builder version.

For the builder version 1.x, the directive is optional. If a query or mutation doesn't have the directive, it's considered public by default. For the builder version 2.x, the directive is mandatory.

To enable authorization, you must add the @auth directive to the specific fields or operations in your GraphQL schema that need protection. This directive ensures that only requesters with access to the corresponding License Manager resource are allowed to execute the operation.

The @auth directive uses the following arguments:

ArgumentDescriptionBuilder version details
scope

The authorization scope of the query or mutation. It has two possible values:

  • PUBLIC: The query is public, so it doesn't require any authorization. This scope is mostly used for shoppers browsing a store.
  • PRIVATE: The query is private, which requires authorization for a specific License Manager resource and product. This scope should be used for scenarios other than store browsing by a shopper, such as in the Admin.
Works only on version 2.x, and is mandatory.
productCodeThe numeric code that identifies the product in License Manager (for example, "66" for VTEX IO). See the product codes in the Product ID column of the table in License Manager resources.Works on versions 1.x and 2.x. For 2.x, this argument is mandatory if scope is set to PRIVATE.
resourceCodeThe License Manager resource identifier (for example, "workspace-read-write" for Workspace CRUD). See the resource codes in the Key column of the table in License Manager resources.Works on versions 1.x and 2.x. For 2.x, this argument is mandatory if scope is set to PRIVATE.

Examples:

With version 1.x:


_10
type Mutation {
_10
createWorkspace(account: String, workspace: String): GenericResponse
_10
@auth(productCode: "66", resourceCode: "workspace-read-write")
_10
}

Public with version 2.x:


_10
type Query {
_10
source(id: ID!): String
_10
@auth(scope: PUBLIC)
_10
}

In this example, there is no verification of whether the requester has access to a specific License Manager resource.

Private with version 2.x:


_10
type Mutation {
_10
createWorkspace(account: String, workspace: String): GenericResponse
_10
@auth(scope: PRIVATE, productCode: "66", resourceCode: "workspace-read-write")
_10
}

In this example, when the user requests the createWorkspace mutation, VTEX checks if the user has access to the workspace-read-write resource from License Manager. If the user has this access, the endpoint will be processed as intended. Otherwise, the request will be denied.

You can see the available products and resources in License Manager resources.

Error scenarios

If a developer tries to build an app with the GraphQL builder 2.x, the VTEX IO CLI will show an error message in the following cases:

  • Any query or mutation lacks the @auth directive.
  • The scope argument is missing in the directive.
  • When scope is PRIVATE in the directive and the productCode or resourceCode arguments are missing.

An error occurred while loading the image ../../images/graphql-auth-directive-error.png

Making requests to protected GraphQL APIs from a VTEX IO app

When making requests to a protected GraphQL API from another VTEX IO app, you must export a custom Client that extends the AppGraphQLClient type and set the VtexIdclientAutCookie header with the auth token in the Client. The requester must have the role or policy that includes the resourceCode and productCode defined in the target operation's @auth directive.

Declare the token based on the requester's context:

  • App: ctx.authToken.
  • Admin user: ctx.adminUserAuthToken.

Example

node/clients/catalogGraphQL/index.ts

_12
import { AppGraphQLClient, InstanceOptions, IOContext } from '@vtex/api'
_12
export class CatalogGQL extends AppGraphQLClient {
_12
constructor(ctx: IOContext, options?: InstanceOptions) {
_12
super('vtex.catalog-graphql@1.x', ctx, {
_12
...options,
_12
headers: {
_12
...options?.headers,
_12
VtexIdclientAutCookie: ctx.adminUserAuthToken,
_12
},
_12
})
_12
}
_12
}

For details about token types, see App authentication using auth tokens.

Use the user token (Admin) whenever possible to properly identify the requester. The app token (ctx.authToken) should only be used when the user can't access the requested service.

Making requests to protected GraphQL APIs of apps

When making external requests to a GraphQL API of an app, include the user token in the VtexIdclientAutCookie HTTP header. The requester must have a role that includes the resource and product defined in the endpoint's @auth directive.

Example (cURL):

terminal

_32
curl -X POST \
_32
'https://https://app.io.vtex.com/vtex.rewriter/v1/{account}/_v/graphql' \
_32
-H 'Content-Type: application/json' \
_32
-H 'VtexIdclientAutCookie: {your_user_token}' \
_32
-d '{
_32
"query": "
_32
mutation SaveInternal($route: InternalInput!) {
_32
internal {
_32
save(route: $route) {
_32
from
_32
id
_32
type
_32
binding
_32
resolveAs
_32
origin
_32
}
_32
}
_32
}
_32
",
_32
"variables": {
_32
"route": {
_32
"from": "/old-path",
_32
"declarer": "vtex.store@2.x",
_32
"type": "redirect",
_32
"id": "custom-redirect-old-path",
_32
"binding": "your-binding-id",
_32
"resolveAs": "/new-path",
_32
"origin": "internal",
_32
"disableSitemapEntry": false
_32
}
_32
}
_32
}'

You can make GraphQL requests with GraphQL IDEs that support custom HTTP headers, such as the one in the VTEX Admin. Not all GraphQL IDEs allow setting authentication headers, which may prevent requests to protected operations from being executed successfully.

Contributors
2
Photo of the contributor
Photo of the contributor
Was this helpful?
Yes
No
Suggest Edits (GitHub)
Contributors
2
Photo of the contributor
Photo of the contributor
Was this helpful?
Suggest Edits (GitHub)
On this page