Service auth token

How can I use service auth token for accessing my api securely from my website? If I add my server IP to the whitelist in the "zero trust" application part then I can access it via my website but if not it fails on the authentication via jwt / service auth. Using NodeJS / NPM / NextJS app.
10 Replies
Erina Nakiri
Erina Nakiri•11mo ago
🤨 Someone? Well I can tell that this feature is broken, thanks for clarifying this issue for me. ( great support in this channel)
ted
ted•11mo ago
you are so impatient aren’t you
Erina Nakiri
Erina Nakiri•11mo ago
Listen last time it took 10 days to answer my question.
ted
ted•11mo ago
oh your telling me to listen? like your the boss? it has been literally less then a day since you asked your question your api is behind an application?
Cyb3r-Jak3
Cyb3r-Jak3•11mo ago
My first thought is that the headers aren't being set correctly or the token isn't allowed in the access policy
Erina Nakiri
Erina Nakiri•11mo ago
Yes I just can't understand how to implement the access part in my code. How to do the check if the service auth is correct then allow access without auth, for now I did it by IP, allowed IPs. But I would like to know how to do it via service auth using, nextjs, nodejs. What is the header that I should send, I'm pretty sure I'm sending the wrong one
kian
kian•11mo ago
Service tokens · Cloudflare Zero Trust docs
You can provide automated systems with service tokens to authenticate against your Zero Trust policies. Cloudflare Access will generate service tokens …
Erina Nakiri
Erina Nakiri•11mo ago
This is the server part
const express = require('express');
const jwt = require('jsonwebtoken');
const jwksClient = require('jwks-rsa');

const app = express();

const CF_ACCESS_CLIENT_SECRET = ''; // Your Cloudflare Access Client Secret
const allowedIPs = ['8.8.8.8', '66.6.5.8'];
const allowedReferers = ['example.net', 'test.example.net'];

const client = jwksClient({
jwksUri: 'https://YOUR_CLOUDFLARE_DOMAIN_NAME/cdn-cgi/access/certs'
});

function getKey(header, callback) {
client.getSigningKey(header.kid, function(err, key) {
const signingKey = key.publicKey || key.rsaPublicKey;
callback(null, signingKey);
});
}

app.use((req, res, next) => {
const token = req.headers['cf-access-jwt-assertion'];
const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
const referer = req.headers.referer;
const refererIsAllowed = allowedReferers.some(allowedReferer => referer && referer.includes(allowedReferer));

if (allowedIPs.includes(ip) || refererIsAllowed) {
next();
} else if (token) {
jwt.verify(token, getKey, {
algorithms: ['RS256'],
issuer: `https://YOUR_CLOUDFLARE_DOMAIN_NAME/`
}, (err, decoded) => {
if (err) {
return res.status(401).send('Failed to authenticate token');
}
req.user = decoded;
next();
});
} else {
return res.status(403).send('Access denied');
}
});
const express = require('express');
const jwt = require('jsonwebtoken');
const jwksClient = require('jwks-rsa');

const app = express();

const CF_ACCESS_CLIENT_SECRET = ''; // Your Cloudflare Access Client Secret
const allowedIPs = ['8.8.8.8', '66.6.5.8'];
const allowedReferers = ['example.net', 'test.example.net'];

const client = jwksClient({
jwksUri: 'https://YOUR_CLOUDFLARE_DOMAIN_NAME/cdn-cgi/access/certs'
});

function getKey(header, callback) {
client.getSigningKey(header.kid, function(err, key) {
const signingKey = key.publicKey || key.rsaPublicKey;
callback(null, signingKey);
});
}

app.use((req, res, next) => {
const token = req.headers['cf-access-jwt-assertion'];
const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
const referer = req.headers.referer;
const refererIsAllowed = allowedReferers.some(allowedReferer => referer && referer.includes(allowedReferer));

if (allowedIPs.includes(ip) || refererIsAllowed) {
next();
} else if (token) {
jwt.verify(token, getKey, {
algorithms: ['RS256'],
issuer: `https://YOUR_CLOUDFLARE_DOMAIN_NAME/`
}, (err, decoded) => {
if (err) {
return res.status(401).send('Failed to authenticate token');
}
req.user = decoded;
next();
});
} else {
return res.status(403).send('Access denied');
}
});
A friend tried to help me with it but we couldn't understand how to do it 🙂 Tried with curl still the same result, "error cloudflare permission denied" Now I can see I get, failed to authenticate with token, new token I see the access get into the cloudflare but does nothing Via curl in Linux terminal Nvrm fixed
ted
ted•11mo ago
would you like to share your soulotion in case anyone else experiencing the same problem yh ikr
Erina Nakiri
Erina Nakiri•11mo ago
Found an issue with some security solution I made on the API side that blocked the connection while trying only via service auth since I removed the server IP from the list of IPs in the allowed list there.. The allowed IPs are now managed only via the application part in zero trust alongside the service auth Even that was just super weird because the request never arrived to my server while my security part in the code was enabled. It just got "invalid headers" but I couldn't see the request at all on the API side.