MFA
-
You don't need to run the commands from inside the container. You can add an ACL allowing the IP address of the host system or your LAN subnet (as
source_ip). But in any case, once you add the user/group ACL entry to permit the endpoint as suggested above, as long as that entry also doesn't restrict IP (i.e. doesn't containsource_ip), any IP that can log in as that user (or a user in that group, if group), will be allowed from anywhere (i.e. authorized queries from outside the container will work). -
You don't need to run the commands from inside the container. You can add an ACL allowing the IP address of the host system or your LAN subnet (as
source_ip). But in any case, once you add the user/group ACL entry to permit the endpoint as suggested above, as long as that entry also doesn't restrict IP (i.e. doesn't containsource_ip), any IP that can log in as that user (or a user in that group, if group), will be allowed from anywhere (i.e. authorized queries from outside the container will work).@toggledbits I honestly did not recall implementing any ACL or Access Control settings outside of adding a user.
That to say, this morning when I went in to start that work, I found entries in place. No recollection of adding them - but it made all of the above suddenly make much more sense.
I can remove the above post if it's way out.
-
You don't need to run the commands from inside the container. You can add an ACL allowing the IP address of the host system or your LAN subnet (as
source_ip). But in any case, once you add the user/group ACL entry to permit the endpoint as suggested above, as long as that entry also doesn't restrict IP (i.e. doesn't containsource_ip), any IP that can log in as that user (or a user in that group, if group), will be allowed from anywhere (i.e. authorized queries from outside the container will work).This is what I see in my reactor.log file:
[latest-26298]2026-10-28T16:27:53.505Z <httpapi:5:httpapi.js:1122> httpapi#1 starting request from "192.168.1.123" via ::ffff:192.168.1.123 for GET /api/v1/mfa.add/tmorgenthaler?askauth=1 lang en-US,en;q=0.9 (TLSv1.3) [latest-26298]2026-10-28T16:27:53.505Z <httpapi:5:httpapi.js:1154> httpapi#1 auth header Basic dG1vcmdlbnRoYWxlcjohUjNicjNhdGgzciE= [latest-26298]2026-10-28T16:27:53.517Z <httpapi:5:httpapi.js:1161> httpapi#1 auth accepted via HTTP Basic user tmorgenthaler [latest-26298]2026-10-28T16:27:53.517Z <httpapi:INFO> httpapi#1 API request from ::ffff:192.168.1.123 (TLSv1.3): GET /api/v1/mfa.add/tmorgenthaler [latest-26298]2026-10-28T16:27:53.517Z <httpapi:INFO> httpapi#1 request for /api/v1/mfa.add/tmorgenthaler from ::ffff:192.168.1.123 user tmorgenthaler auth basic matches / ACL (#6): { "url": "/", "allow": false, "index": 6 }I'm assuming the "allow": false is the deny.
The allowed list in my reactor.yaml covers that IP:
allowed_ips: # - "127.0.0.1" # - "192.168.0." # or whatever your local trusted subnet - "192.168.1.0/24" -
The allowed list is separate from ACLs. It's just a first check. The ACLs are next. The former doesn't imply the latter, the latter having much more granularity/detail.
-
The allowed list is separate from ACLs. It's just a first check. The ACLs are next. The former doesn't imply the latter, the latter having much more granularity/detail.
@toggledbits said in MFA:
The allowed list is separate from ACLs. It's just a first check. The ACLs are next.
Okay, I added my /24 to the allowed api in users.yaml
groups: api_allowed: users: - admin - tmorgenthaler api_acls: - url: "/api/" group: api_allowed source_IP: 192.168.1.1/24 allow: truebut I'm still not getting anywhere:
[latest-26298]2026-10-28T18:22:12.362Z <wsapi:5:wsapi.js:169> (event handler): sending data [latest-26298]2026-10-28T18:22:12.379Z <wsapi:5:wsapi.js:152> (event handler) sending update for 20 entities [latest-26298]2026-10-28T18:22:13.139Z <wsapi:5:wsapi.js:169> (event handler): sending data [latest-26298]2026-10-28T18:22:13.164Z <wsapi:5:wsapi.js:152> (event handler) sending update for 1 entities root@docker:/home/tmorgenthaler/reactor/logs# cat httpapi.log | grep auth [latest-26298]2026-10-28T18:18:50.085Z <httpapi:CRIT> httpapi#1 ACLs Array(7) [{ "url": "/api/v1/authorize", "allow": true, "index": 0 }, { "url": "/api/v1/deauthorize", "allow": true, "index": 1 }, { "url": "/api/v1/systime", "allow": true, "index": 2 }, { "url": "/api/v1/alive", "allow": true, "index": 3 }, { "url": "/api/v1/lang", "allow": true, "index": 4 }, { "url": "/api", "source_ip": "127/8", "allow": true, "index": 5 }, { "url": "/", "allow": false, "index": 6 }] [latest-26298]2026-10-28T18:18:50.086Z <httpapi:CRIT> httpapi#1 ACL index Map(7) {"/api/v1/authorize": Array(1) [0], "/api/v1/deauthorize": Array(1) [1], "/api/v1/systime": Array(1) [2], "/api/v1/alive": Array(1) [3], "/api/v1/lang": Array(1) [4], "/api": Array(1) [5], "/": Array(1) [6] } [latest-26298]2026-10-28T18:18:52.748Z <httpapi:5:httpapi.js:820> httpapi#1 purging expired authorizations; default delay 7200000 [latest-26298]2026-10-28T18:18:52.748Z <httpapi:5:httpapi.js:848> httpapi#1 setting timer for next authorization purge in 7200000ms [latest-26298]2026-10-28T18:19:12.395Z <httpapi:5:httpapi.js:1122> httpapi#1 starting request from "192.168.1.123" via ::ffff:192.168.1.123 for GET /api/v1/mfa.add/tmorgenthaler?askauth=1 lang en-US,en;q=0.9 (TLSv1.3) [latest-26298]2026-10-28T18:19:12.396Z <httpapi:5:httpapi.js:1154> httpapi#1 auth header Basic dG1vcmdlbnRoYWxlcjohUjNicjNhdGgzciE= [latest-26298]2026-10-28T18:19:12.407Z <httpapi:5:httpapi.js:1161> httpapi#1 auth accepted via HTTP Basic user tmorgenthaler [latest-26298]2026-10-28T18:19:12.408Z <httpapi:INFO> httpapi#1 request for /api/v1/mfa.add/tmorgenthaler from ::ffff:192.168.1.123 user tmorgenthaler auth basic matches / ACL (#6): { "url": "/", "allow": false, "index": 6 } [latest-26298]2026-10-28T18:19:34.975Z <httpapi:5:httpapi.js:1122> httpapi#1 starting request from "192.168.1.123" via ::ffff:192.168.1.123 for GET /api/v1/mfa.add/tmorgenthaler?askauth=1 lang en-US,en;q=0.9 (TLSv1.3) [latest-26298]2026-10-28T18:19:34.975Z <httpapi:5:httpapi.js:1221> httpapi#1 askauth! [latest-26298]2026-10-28T18:19:47.485Z <httpapi:5:httpapi.js:1122> httpapi#1 starting request from "192.168.1.123" via ::ffff:192.168.1.123 for GET /api/v1/mfa.add/tmorgenthaler?askauth=1 lang en-US,en;q=0.9 (TLSv1.3) [latest-26298]2026-10-28T18:19:47.485Z <httpapi:5:httpapi.js:1154> httpapi#1 auth header Basic dG1vcmdlbnRoYWxlcjohUjNicjNhdGgzciE= [latest-26298]2026-10-28T18:19:47.495Z <httpapi:5:httpapi.js:1161> httpapi#1 auth accepted via HTTP Basic user tmorgenthaler [latest-26298]2026-10-28T18:19:47.495Z <httpapi:INFO> httpapi#1 request for /api/v1/mfa.add/tmorgenthaler from ::ffff:192.168.1.123 user tmorgenthaler auth basic matches / ACL (#6): { "url": "/", "allow": false, "index": 6 } [latest-26298]2026-10-28T18:19:54.970Z <httpapi:5:httpapi.js:1122> httpapi#1 starting request from "192.168.1.123" via ::ffff:192.168.1.123 for GET /api/v1/mfa.add/tmorgenthaler?askauth=1 lang en-US,en;q=0.9 (TLSv1.3) [latest-26298]2026-10-28T18:19:54.970Z <httpapi:5:httpapi.js:1154> httpapi#1 auth header Basic dG1vcmdlbnRoYWxlcjohUjNicjNhdGgzciE= [latest-26298]2026-10-28T18:19:54.979Z <httpapi:5:httpapi.js:1161> httpapi#1 auth accepted via HTTP Basic user tmorgenthaler [latest-26298]2026-10-28T18:19:54.979Z <httpapi:INFO> httpapi#1 request for /api/v1/mfa.add/tmorgenthaler from ::ffff:192.168.1.123 user tmorgenthaler auth basic matches / ACL (#6): { "url": "/", "allow": false, "index": 6 } [latest-26298]2026-10-28T18:20:01.600Z <httpapi:5:httpapi.js:1122> httpapi#1 starting request from "192.168.1.123" via ::ffff:192.168.1.123 for GET /api/v1/mfa.add/tmorgenthaler?askauth=1 lang en-US,en;q=0.9 (TLSv1.3) [latest-26298]2026-10-28T18:20:01.600Z <httpapi:5:httpapi.js:1154> httpapi#1 auth header Basic dG1vcmdlbnRoYWxlcjohUjNicjNhdGgzciE= [latest-26298]2026-10-28T18:20:01.607Z <httpapi:5:httpapi.js:1161> httpapi#1 auth accepted via HTTP Basic user tmorgenthaler [latest-26298]2026-10-28T18:20:01.607Z <httpapi:INFO> httpapi#1 request for /api/v1/mfa.add/tmorgenthaler from ::ffff:192.168.1.123 user tmorgenthaler auth basic matches / ACL (#6): { "url": "/", "allow": false, "index": 6 } [latest-26298]2026-10-28T18:20:10.938Z <httpapi:5:httpapi.js:1122> httpapi#1 starting request from "192.168.1.123" via ::ffff:192.168.1.123 for GET /api/v1/mfa.add/tmorgenthaler?askauth=1 lang en-US,en;q=0.9 (TLSv1.3) [latest-26298]2026-10-28T18:20:10.938Z <httpapi:5:httpapi.js:1221> httpapi#1 askauth! [latest-26298]2026-10-28T18:20:54.025Z <httpapi:5:httpapi.js:1122> httpapi#1 starting request from "192.168.1.123" via ::ffff:192.168.1.123 for GET /api/v1/mfa.add/tmorgenthaler?askauth=1 lang en-US,en;q=0.9 (TLSv1.3) [latest-26298]2026-10-28T18:20:54.025Z <httpapi:5:httpapi.js:1154> httpapi#1 auth header Basic dG1vcmdlbnRoYWxlcjohUjNicjNhdGgzciE= [latest-26298]2026-10-28T18:20:54.040Z <httpapi:5:httpapi.js:1161> httpapi#1 auth accepted via HTTP Basic user tmorgenthaler [latest-26298]2026-10-28T18:20:54.040Z <httpapi:INFO> httpapi#1 request for /api/v1/mfa.add/tmorgenthaler from ::ffff:192.168.1.123 user tmorgenthaler auth basic matches / ACL (#6): { "url": "/", "allow": false, "index": 6 } root@docker:/home/tmorgenthaler/reactor/logs# cat httpapi.log | grep 18:20:54 [latest-26298]2026-10-28T18:20:54.025Z <httpapi:5:httpapi.js:1122> httpapi#1 starting request from "192.168.1.123" via ::ffff:192.168.1.123 for GET /api/v1/mfa.add/tmorgenthaler?askauth=1 lang en-US,en;q=0.9 (TLSv1.3) [latest-26298]2026-10-28T18:20:54.025Z <httpapi:5:httpapi.js:1154> httpapi#1 auth header Basic dG1vcmdlbnRoYWxlcjohUjNicjNhdGgzciE= [latest-26298]2026-10-28T18:20:54.040Z <httpapi:5:httpapi.js:1161> httpapi#1 auth accepted via HTTP Basic user tmorgenthaler [latest-26298]2026-10-28T18:20:54.040Z <httpapi:INFO> httpapi#1 API request from ::ffff:192.168.1.123 (TLSv1.3): GET /api/v1/mfa.add/tmorgenthaler [latest-26298]2026-10-28T18:20:54.040Z <httpapi:INFO> httpapi#1 request for /api/v1/mfa.add/tmorgenthaler from ::ffff:192.168.1.123 user tmorgenthaler auth basic matches / ACL (#6): { "url": "/", "allow": false, "index": 6 } [latest-26298]2026-10-28T18:20:54.042Z <wsapi:5:wsapi.js:169> (event handler): sending data [latest-26298]2026-10-28T18:20:54.042Z <wsapi:5:wsapi.js:169> (event handler): sending data [latest-26298]2026-10-28T18:20:54.067Z <wsapi:5:wsapi.js:152> (event handler) sending update for 2 entities [latest-26298]2026-10-28T18:20:54.749Z <wsapi:5:wsapi.js:169> (event handler): sending data [latest-26298]2026-10-28T18:20:54.775Z <wsapi:5:wsapi.js:152> (event handler) sending update for 1 entities [latest-26298]2026-10-28T18:20:54.836Z <wsapi:5:wsapi.js:169> (event handler): sending data [latest-26298]2026-10-28T18:20:54.836Z <wsapi:5:wsapi.js:169> (event handler): sending data [latest-26298]2026-10-28T18:20:54.861Z <wsapi:5:wsapi.js:152> (event handler) sending update for 2 entities -
Are you requesting from a browser or curl?
Edit: also
source_IPmust besource_ip(all lower case). -
See edit above
-
Still no joy. I'm still getting Access Denied after entering my username and password
[latest-26298]2026-10-30T11:39:27.726Z <wsapi:5:wsapi.js:169> (event handler): sending data [latest-26298]2026-10-30T11:39:27.735Z <wsapi:5:wsapi.js:152> (event handler) sending update for 5 entities [latest-26298]2026-10-30T11:39:27.982Z <httpapi:5:httpapi.js:1122> httpapi#1 starting request from "192.168.1.127" via ::ffff:192.168.1.127 for GET /api/v1/mfa.add/tmorgenthaler?askauth=1 lang en-US,en;q=0.9 (TLSv1.3) [latest-26298]2026-10-30T11:39:27.982Z <httpapi:5:httpapi.js:1154> httpapi#1 auth header Basic dG1vcmdlbnRoYWxlcjohUjNicjNhdGgzciE= [latest-26298]2026-10-30T11:39:27.990Z <httpapi:5:httpapi.js:1161> httpapi#1 auth accepted via HTTP Basic user tmorgenthaler [latest-26298]2026-10-30T11:39:27.991Z <httpapi:INFO> httpapi#1 API request from ::ffff:192.168.1.127 (TLSv1.3): GET /api/v1/mfa.add/tmorgenthaler [latest-26298]2026-10-30T11:39:27.991Z <httpapi:INFO> httpapi#1 request for /api/v1/mfa.add/tmorgenthaler from ::ffff:192.168.1.127 user tmorgenthaler auth basic matches / ACL (#6): { "url": "/", "allow": false, "index": 6 } [latest-26298]2026-10-30T11:39:28.264Z <wsapi:5:wsapi.js:169> (event handler): sending data [latest-26298]2026-10-30T11:39:28.265Z <wsapi:5:wsapi.js:169> (event handler): sending data [latest-26298]2026-10-30T11:39:28.265Z <wsapi:5:wsapi.js:169> (event handler): sending datagroups: api_allowed: users: - admin - tmorgenthaler api_acls: - url: "/api/" group: api_allowed source_ip: 192.168.1.1/24 allow: true -
Still no joy. I'm still getting Access Denied after entering my username and password
[latest-26298]2026-10-30T11:39:27.726Z <wsapi:5:wsapi.js:169> (event handler): sending data [latest-26298]2026-10-30T11:39:27.735Z <wsapi:5:wsapi.js:152> (event handler) sending update for 5 entities [latest-26298]2026-10-30T11:39:27.982Z <httpapi:5:httpapi.js:1122> httpapi#1 starting request from "192.168.1.127" via ::ffff:192.168.1.127 for GET /api/v1/mfa.add/tmorgenthaler?askauth=1 lang en-US,en;q=0.9 (TLSv1.3) [latest-26298]2026-10-30T11:39:27.982Z <httpapi:5:httpapi.js:1154> httpapi#1 auth header Basic dG1vcmdlbnRoYWxlcjohUjNicjNhdGgzciE= [latest-26298]2026-10-30T11:39:27.990Z <httpapi:5:httpapi.js:1161> httpapi#1 auth accepted via HTTP Basic user tmorgenthaler [latest-26298]2026-10-30T11:39:27.991Z <httpapi:INFO> httpapi#1 API request from ::ffff:192.168.1.127 (TLSv1.3): GET /api/v1/mfa.add/tmorgenthaler [latest-26298]2026-10-30T11:39:27.991Z <httpapi:INFO> httpapi#1 request for /api/v1/mfa.add/tmorgenthaler from ::ffff:192.168.1.127 user tmorgenthaler auth basic matches / ACL (#6): { "url": "/", "allow": false, "index": 6 } [latest-26298]2026-10-30T11:39:28.264Z <wsapi:5:wsapi.js:169> (event handler): sending data [latest-26298]2026-10-30T11:39:28.265Z <wsapi:5:wsapi.js:169> (event handler): sending data [latest-26298]2026-10-30T11:39:28.265Z <wsapi:5:wsapi.js:169> (event handler): sending datagroups: api_allowed: users: - admin - tmorgenthaler api_acls: - url: "/api/" group: api_allowed source_ip: 192.168.1.1/24 allow: true










