I'm using pubsub to push messages into an App Engine app written in node on the flexible environment. Is there a way I can limit my endpoints to only traffic from pubsub?
In the standard environment, App Engine has handlers that can define admin only requests and secure endpoints. However, this functionality is not available in the flexible environment. Is it possible to set up Firewall rules for only Google requests (Firewall appears to be application wide, not endpoint?), is there a standard method to secure endpoints or do I need to custom roll a solution?
Turns out Google has posted a solution to this in the docs.
The solution is:
Create a token in your app.yaml environment:
env_variables:
PUBSUB_TOPIC: <your-topic-name>
# This token is used to verify that requests originate from your
# application. It can be any sufficiently random string.
PUBSUB_VERIFICATION_TOKEN: <your-verification-token>
Send the token with your message:
https://YOUR_APP_ID.appspot.com/pubsub/push?token=YOUR_TOKEN \
--ack-deadline 10
Check the token in your push handler:
if (req.query.token !== PUBSUB_VERIFICATION_TOKEN) {
res.status(400).send();
return;
}
RTFM!
This is an old post, using a hardcoded verification token is not a recommended secure approach.
The docs are not exactly clear for App Engine and I raised an issue to see if they can improve.
Authorization header and use the OAuth2Client from google-auth-library to parse and validate itThe GCP docs page does not show this example, although their samples repo shows it, albeit with some confusing code.
If you are using express then steps 2,3 are suited to middleware and we have written a simple small library with the appropriate middleware for you to use. See gae-js-google-auth and the example below for validating the email matches your desired service account email (as well as the internal assertions that the lib does).
// Apply middleware however you normally would
app.use("/pubsub", requiresGoogleJwt({
email: "[email protected]"
}));
// Now any matching routes will be protected
app.post("/pubsub/start-job", (req, res) => res.send("OK"));
app.post("/pubsub/poll-status", (req, res) => res.send("OK"));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With