Skip to content

Commit

Permalink
Added securing your backend with secret example
Browse files Browse the repository at this point in the history
  • Loading branch information
ntotten committed Sep 5, 2024
1 parent 2d5c36c commit 55cfd26
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 4 deletions.
81 changes: 81 additions & 0 deletions docs/articles/securing-backend-shared-secret.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
---
title: Securing your Backend with a Shared Secret
---

When using a gateway, it's important to ensure that your backend API only
accepts traffic from the gateway. This ensures that policies and security are
applied to all traffic. Zuplo offers
[multiple options for securing your backend](./securing-your-backend.md) API.
This article will show you the simplest option, which is using a shared secret
via a header.

## 1/ Set an Environment Variable

The first step is to set an
[environment variable](https://zuplo.com/docs/articles/environment-variables) in
your Zuplo project. This variable will be a secret that only your Zuplo project
and your backend know. This secret will be sent as a header on every request to
your backend API.

Open the _Settings_ section of your project and select _Environment Variables_.
Create a new variable and name it `BACKEND_SECRET`. Set the value to a secure,
random value. Ensure that the value is marked as a secret.

![Set Environment Variable](../../public/media/securing-backend-shared-secret/image.png)

## 2/ Create a Set Header Policy

The next step is to create a policy that sets the `BACKEND_SECRET` as a header
on the request to your backend API. This policy will be an outbound policy that
runs before the request is sent to your backend.

Navigate to the route you want to secure and add a new policy. Select the **Add
or Set Request Headers** policy type and configure it as follows:

![Set Header Policy](../../public/media/securing-backend-shared-secret/image-1.png)

The configuration uses the environment variable via the `$env(BACKEND_SECRET)`
selector as shown below.

```json
{
"name": "set-backend-secret",
"policyType": "set-headers-inbound",
"handler": {
"export": "SetHeadersInboundPolicy",
"module": "$import(@zuplo/runtime)",
"options": {
"headers": [
{
"name": "backend-secret",
"value": "$env(BACKEND_SECRET)"
}
]
}
}
}
```

Add this policy to any of the routes in your API that are calling your secure
backend.

# 3/ Verify the Secret on your Backend

Finally, you need to verify the secret on your backend. The way you implement
this depends on the framework and language you are using, but the typical
pattern is to use a middleware to check the header value. If the header does not
match the secret, you would typically return a 401 Unauthorized response.

An example of this using a Node.js connect middleware is shown below.

```js
const express = require("express");
const app = express();

app.use((req, res, next) => {
if (req.headers["backend-secret"] !== process.env.BACKEND_SECRET) {
return res.status(401).send("Unauthorized");
}
next();
});
```
6 changes: 3 additions & 3 deletions docs/articles/securing-your-backend.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ Firebase, and Stripe to secure their own APIs. In this solution the backend
requires a secret that is known only by the gateway. This is usually an opaque
key sent as a header on every request to the origin. Zuplo adds this to the
request - the client is never aware of the secret. An example of how to set this
up, including using [Environment Variables](./environment-variables.md) to store
the secret is included in
[Step 1 - Setup a Basic Gateway](./step-1-setup-basic-gateway.md).
up, is show in the
[Securing your Backend with a Shared Secret](./securing-backend-shared-secret.md)
article.

## 2/ Federated Authentication

Expand Down
2 changes: 1 addition & 1 deletion policies/custom-code-inbound/doc.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ Here's how we could wire up our new auth route:
"policies": [
{
"name": "my-first-policy",
"policyType": "custom-code",
"policyType": "custom-code-inbound",
"handler": {
"export": "default",
"module": "$import(./modules/my-first-policy)"
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 55cfd26

Please sign in to comment.