# Add permissions to API keys

**URL:** <https://forums.balena.io/t/add-permissions-to-api-keys/230775>\
**Category:** openBalena\
**Created:** [January 5, 2021, 10:34am UTC](https://forums.balena.io/t/add-permissions-to-api-keys/230775 "2021-01-05T10:34:12Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![bversluijs](https://sea2.discourse-cdn.com/balena/user_avatar/forums.balena.io/bversluijs/32/3954_2.png) [@bversluijs](https://forums.balena.io/u/bversluijs)\
**Post date:** [January 5, 2021, 10:34am UTC](https://forums.balena.io/t/add-permissions-to-api-keys/230775/1 "2021-01-05T10:34:12Z")

</div>

Hi all,

I was busy with the VPN HTTP Proxy via port 3128, so that I can access certain parts of my application from our server. Just like Balena does with the supervisor. However, if I try that, I get a 407 error. I’ve looked into the code and saw [that it checks for access](https://github.com/balena-io/open-balena-vpn/blob/master/src/proxy-worker.ts#L183). If I’m correct, [this part](https://github.com/balena-io/open-balena-vpn/blob/master/src/proxy-worker.ts#L183) asks the API if I have access to `tunnel-any` or `tunnel-<port>`.

However, looking into the `open-balena-api` (if I’m correct), only [tunnel-48484](https://github.com/balena-io/open-balena-vpn/blob/master/src/proxy-worker.ts#L183) is allowed for the VPN API key. It’s obviously for security reasons, but I’d like to use the VPN for my own application and allow another port to be tunneled via the HTTP proxy.

Is there any way to achieve this via openBalena? I’ve created the tunnel the same way as done [here](https://github.com/balena-io/open-balena-api/blob/master/src/features/device-proxy/device-proxy.ts#L248).

I know it’s for (obvious) security reasons that it’s not included by default, but because I’m using openBalena, it’d be nice if I can add this functionality for my server. Or is the only way to fork the `open-balena-api` and publish my own container?

Thanks in advance!

---

<div class="post-metadata">

**Author:** ![richbayliss](https://sea2.discourse-cdn.com/balena/user_avatar/forums.balena.io/richbayliss/32/1054_2.png) [@richbayliss](https://forums.balena.io/u/richbayliss)\
**Post date:** [January 5, 2021, 12:11pm UTC](https://forums.balena.io/t/add-permissions-to-api-keys/230775/4 "2021-01-05T12:11:27Z")

</div>

> Or is the only way to fork the open-balena-api and publish my own container?

If you want to change these permissions, then this is the way.

The VPN key can only use 48484 as it’s done to allow access to the device’ supervisor API. When using the CLI `tunnel` command, the users key is used and that’s where the `tunnel-any` comes into play. I think you worked that out, but I though it good to confirm here 👍

---

<div class="post-metadata">

**Author:** ![bversluijs](https://sea2.discourse-cdn.com/balena/user_avatar/forums.balena.io/bversluijs/32/3954_2.png) [@bversluijs](https://forums.balena.io/u/bversluijs)\
**Post date:** [January 5, 2021, 12:16pm UTC](https://forums.balena.io/t/add-permissions-to-api-keys/230775/6 "2021-01-05T12:16:17Z")

</div>

Thanks for your confirmation!

I’m going to check how the `tunnel` command works and if I can automate it via Node.js, so I don’t need to create and maintain my own container for the `open-balena-api`. But it’s nice to know how it works and what my options are, so thanks!

---

<div class="post-metadata">

**Author:** ![bversluijs](https://sea2.discourse-cdn.com/balena/user_avatar/forums.balena.io/bversluijs/32/3954_2.png) [@bversluijs](https://forums.balena.io/u/bversluijs)\
**Post date:** [January 5, 2021, 2:40pm UTC](https://forums.balena.io/t/add-permissions-to-api-keys/230775/7 "2021-01-05T14:40:49Z")

</div>

I’ve checked how the `tunnel` command works, and I’ve been able to come up with something that works exactly as I want!

I’m using Node.js, so I’ve used the Node.js Balena SDK for it. This is how I’ve done it:

```auto
import { getSdk } from 'balena-sdk';
import request from 'request';

const balenaInstance = getSdk({ apiUrl: 'api.<open-balena-domain>' });
await balenaInstance.auth.login(credentials);

const [whoami, token] = Promise.all([
  balenaInstance.auth.whoami(),
  balenaInstance.auth.getToken()
]);

await new Promise((resolve, reject) => {
  request({
    uri: `http://<device-uuid>.balena:<device-port>',
    tunnel: true,
    proxy: `http://${whoami}:${token}@vpn.<open-balena-domain>:3128`
  }, (err, response) => {
    if (err) {
      reject(err);
    } else {
      resolve(response);
    }
  });
});

```

* * *

I don’t know if this works for Balena Cloud though, because of permissions.

---

<div class="post-metadata">

**Author:** ![richbayliss](https://sea2.discourse-cdn.com/balena/user_avatar/forums.balena.io/richbayliss/32/1054_2.png) [@richbayliss](https://forums.balena.io/u/richbayliss)\
**Post date:** [January 5, 2021, 2:55pm UTC](https://forums.balena.io/t/add-permissions-to-api-keys/230775/8 "2021-01-05T14:55:30Z")

</div>

It would work if you used a User-scoped API key (which you have done here) as the `tunnel-any` is a catch all for ports not explicitly allowed.

---

<div class="post-metadata">

**Author:** ![bversluijs](https://sea2.discourse-cdn.com/balena/user_avatar/forums.balena.io/bversluijs/32/3954_2.png) [@bversluijs](https://forums.balena.io/u/bversluijs)\
**Post date:** [January 5, 2021, 2:56pm UTC](https://forums.balena.io/t/add-permissions-to-api-keys/230775/9 "2021-01-05T14:56:54Z")

</div>

Yeah, but I thought that the VPN always uses its own key. But I was wrong there.  
Nonetheless, thanks for pointing me in the right direction!

---

<div class="post-metadata">

**Author:** ![Razikus](https://avatars.discourse-cdn.com/v4/letter/r/e19b73/32.png) [@Razikus](https://forums.balena.io/u/Razikus)\
**Post date:** [January 5, 2021, 10:58pm UTC](https://forums.balena.io/t/add-permissions-to-api-keys/230775/11 "2021-01-05T22:58:44Z")

</div>

Hello

Maybe i don’t understand problem here, but i succesfully tunnel any port from device on Open Balena  
Check this project

This is the ported tunneler to python

> <https://github.com/Razikus/open-balena-tunneler/blob/master/tunneler/tunneler/lib/tunneler.py#L50>

Example usage

> <https://github.com/Razikus/open-balena-tunneler/blob/master/tunneler/tunneler/main.py>

---

<div class="post-metadata">

**Author:** ![bversluijs](https://sea2.discourse-cdn.com/balena/user_avatar/forums.balena.io/bversluijs/32/3954_2.png) [@bversluijs](https://forums.balena.io/u/bversluijs)\
**Post date:** [January 6, 2021, 8:43am UTC](https://forums.balena.io/t/add-permissions-to-api-keys/230775/12 "2021-01-06T08:43:37Z")

</div>

Hi Adam,

Thanks for sharing your code!  
There isn’t really a problem anymore, because I’ve achieved what I wanted [here](https://forums.balena.io/t/add-permissions-to-api-keys/230775/7).

I used the wrong credentials when connecting to the VPN HTTP Proxy, which didn’t allow tunneling ports other than 48484 (supervisor). When using the right credentials (the openBalena login credentials), everything worked as expected!
