Skip to main content

2 posts tagged with "auth0"

View All Tags

What's new in Exograph 0.4

· 5 min read
Ramnivas Laddad
Co-founder @ Exograph
Shadaj Laddad
Co-founder @ Exograph

We are excited to announce the release of Exograph 0.4! This release introduces several new features and enhancements, many in response to our users' feedback (thank you!). While we will explore some of these features in future blogs, here is a quick summary of what's new since the 0.3 version.

NPM modules support

Exograph offers a Deno integration to write custom business logic in TypeScript or JavaScript. Until now, you could only use Deno modules. While Deno modules ecosystem continues to expand, it is not as rich as the Node ecosystem. Recognizing this, Deno added support for NPM modules to tap into the vast range of NPM packages, and Exograph 0.4 extends this support through our integration. You can now harness NPM modules to checkout with Stripe, send messages with Slack, interact with AWS, and so on.

As an illustration, here is how you would send emails using Resend. First, you would define a mutation:

@deno("email.ts")
module Email {
@access(true)
mutation sendAnnouncement(): Boolean
}

And implement it using the resend NPM module:

import { Resend } from "npm:resend";

const resend = new Resend("re_...");

export async function sendAnnouncement(): Promise<boolean> {
await resend.emails.send({
from: "...",
to: "...",
subject: "Exograph 0.4 is out!",
html: "<p>Exograph <strong>0.4</strong> is out with support for npm modules, playground mode, and more!</p>",
});

return true;
}

Compared to the example shown on the Resend site, the difference is the npm: prefix in the import statement. This prefix tells Exograph to look for the module in the npm registry.

Railway integration

Exograph's deployment has always been easy since the server is just a simple binary with everything needed to run. However, we strive to make it easier for specific platforms. Exograph 0.4 now supports Railway as a deployment target! Here is a quick video where we create an Exograph project from scratch and deploy it to Railway in under three minutes.

To support this kind of integration, where the cloud platform can also run the build step, we now publish two Docker images: cli with the exo binary and server with the exo-server binary.

exo playground

A recommended practice for GraphQL deployments is to turn off introspection in production, which is the default in Exograph. However, exploring the GraphQL API with such a server becomes difficult without code completion and other goodies. Exograph 0.4 introduces a new exo playground command that uses the schema from the local server and executes GraphQL operations against the specified remote endpoint.

exo playground --endpoint https://<server-url>/graphql
Starting playground server connected to the endpoint at: https://<server-url>/graphql
- Playground hosted at:
http://localhost:9876/playground

You will see a UI element in the playground showing the specified endpoint. Besides this difference, the playground will behave identically to the local playground, including autocomplete, schema documentation, query history, and integrated authentication.

note

This doesn't bypass the recommended practice of turning off introspection in production. The exo playground is useful only if you have access to the server's source code, in which case, you would know the schema, anyway!

See the video with the Railway integration above for a quick demo of the exo playground command.

Access control improvements

Exograph offers to express access control rules precisely. In version 0.4, we enhanced this expressive power through higher-order functions. Consider a document management system where users can read documents if they have read permissions and mutate if they have written permissions. The following access control rules express this requirement.

context AuthContext {
@jwt("sub") id: Int
}

@postgres
module DocsDatabase {
@access(
query = self.permissions.some(permission => permission.user.id == AuthContext.id && permission.read),
mutation = self.permissions.some(permission => permission.user.id == AuthContext.id && permission.write)
)
type Document {
@pk id: Int = autoIncrement()
...
permissions: Set<Permission>
}

@access(...)
type Permission {
@pk id: Int = autoIncrement()
document: Document
user: User
read: Boolean
write: Boolean
}

@access(...)
type User {
@pk id: Int = autoIncrement()
...
permissions: Set<Permission>
}
}

With this setup, no user can read or write a document without the appropriate permission. The some function allows you to express this requirement in a single line. Internally, it lowers it down to an SQL predicate for efficient execution.

Currently, we support the some higher-order function, which matches the Array.prototype.some function in Javascript. This function takes a predicate function and returns true if the predicate function returns true for any element in the array.

Other improvements

Besides these major features, we continue to improve Exograph to fit more use cases and simplify the developer experience.

For the Postgres plugin, for example, you can now specify that the tables could be in a non-public schema and specify deeply nested creating and updates in a single mutation. It also allows clients to supply the primary key value for UUID fields when creating an entity.

In version 0.3, we introduced a friction-free integration with Clerk for authentication. Since then, we have extended this support to Auth0 as an authentication provider! While Exograph generically supports all compliant OIDC providers, the playground integration for Clerk and Auth0 makes it easy to try out APIs that require authentication. Along the way, we updated key rotation for the OIDC authentication mechanism.

Let us know what you think of these new features and what you would like to see in the future. You can reach us on Twitter or Discord.

Share:

Authentication in Exograph with Auth0

· 4 min read
Ramnivas Laddad
Co-founder @ Exograph

On the heels of Clerk integration, we are excited to announce that Exograph now supports Auth0 as an authentication provider! Exograph's JWT support seamlessly works with Auth0 out of the box. Additionally, Exograph's playground integrates Auth0's authentication UI to simplify the exploration of access control rules.

Our code will be the same as in the previous blog. Since both Clerk and Auth0 support OpenID Connect (OIDC), everything can stay the same.

context AuthContext {
@jwt("sub") id: String
}

@postgres
module TodoDatabase {
@access(self.userId == AuthContext.id)
type Todo {
@pk id: Int = autoIncrement()
title: String
completed: Boolean
userId: String = AuthContext.id
}
}

This is all the code you need for a multi-user todo app! With the rule specified in the @access annotation, each user can only query or mutate their todos.

note

Exograph's @jwt annotation works with any compliant OIDC provider, so you may use it with any other provider. However, the playground integration is currently only available with Clerk and Auth0.

To try it out, create an Auth0 project following their instructions. Pay particular attention to configuring "Allowed Callback URLs" (for this blog, you may set it to http://localhost:9876/playground, http://localhost:3000).

Then you can start the server using exo yolo with the EXO_OIDC_URL environment variable set to your Auth0 URL:

EXO_OIDC_URL=https://<your-auth0-host>.auth0.com exo yolo

This will start the server with Auth0 as the authentication provider.

Auth0 integration with Exograph Playground

A typical workflow for building an app uses the GraphQL API in the playground to try out queries and mutations needed for the frontend and copy those into the frontend code. However, in the presence of authentication, grabbing a JWT token (typically from a partially built UI) and passing it in the Authorization header can be cumbersome. Exograph Playground makes it easy to try out APIs that require authentication by integrating Auth0's UI in the playground.

Try it out. For example, you can execute the following query to get all todos:

query {
todos {
id
title
completed
}
}

If you do so without logging in, you will get an error:

{
"errors": [
{
"message": "Not authorized"
}
]
}

You can log in by clicking the "Authenticate" button in the playground. This will open Auth0's login page in the playground. You can log in using any configured provider (such as Google or Facebook). Once logged in, you can try the query again, and you will see the todos.

Similarly, you can execute mutations. For example, the following mutation will create a new todo:

mutation {
createTodo(data: { title: "Buy milk", completed: false }) {
id
}
}

Due to access control rules, you can create a todo only for the logged-in user.

Lastly, try out the query above by logging in as another user. You will see that the todos created by the first user are not visible to the second user.

Using the frontend

With the confidence that the API works as expected, building a frontend using the same queries and mutations is easy. The accompanying source code is a Next.js app that allows creating todos, marking them as completed, and updating or deleting them.

Clone the examples repository and try it out!

Summary

Combining the declarative backend of Exograph with the authentication of Auth0 is a simple matter of setting the EXO_OIDC_URL environment variable. The playground support makes it a breeze to try out various authentication scenarios to ensure that users access only the data they are supposed to.

We would love to hear your feedback on this integration on our Discord.

Share: