Skip to content

Commit 904d095

Browse files
committed
Node-RED SSO
1 parent 5dc1ff8 commit 904d095

File tree

6 files changed

+937
-43
lines changed

6 files changed

+937
-43
lines changed

nixos-configurations/adama.nix

Lines changed: 84 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
formfactor = "server";
2424

2525
networking.firewall.allowedTCPPorts = [
26-
443 # Nginx
26+
443 # Nginx
2727
# 1880 # Node-RED
2828
1883 # Mosquitto
2929
# 3000 # Grafana
@@ -59,47 +59,89 @@
5959

6060
services.authentik.environmentFile = config.age.secrets.authentik-env.path;
6161

62-
services.authentik.blueprints = [{
63-
metadata.name = "grafana-oauth";
64-
entries = [
65-
{
66-
model = "authentik_providers_oauth2.oauth2provider";
67-
state = "present";
68-
identifiers.name = "Grafana";
69-
id = "provider";
70-
attrs = {
71-
authentication_flow = "!Find [authentik_flows.flow, [slug, default-authentication-flow]]";
72-
authorization_flow = "!Find [authentik_flows.flow, [slug, default-provider-authorization-explicit-consent]]";
73-
client_type = "confidential";
74-
client_id = "grafana";
75-
client_secret = "secret";
76-
access_code_validity = "minutes=1";
77-
access_token_validity = "minutes=5";
78-
refresh_token_validity = "days=30";
79-
property_mappings = [
80-
"!Find [authentik_providers_oauth2.scopemapping, [scope_name, openid]]"
81-
"!Find [authentik_providers_oauth2.scopemapping, [scope_name, email]]"
82-
"!Find [authentik_providers_oauth2.scopemapping, [scope_name, profile]]"
83-
"!Find [authentik_providers_oauth2.scopemapping, [scope_name, offline_access]]"
84-
];
85-
sub_mode = "hashed_user_id";
86-
include_claims_in_id_token = true;
87-
issuer_mode = "per_provider";
88-
};
89-
}
90-
{
91-
model = "authentik_core.application";
92-
state = "present";
93-
identifiers.slug = "grafana";
94-
id = "grafana";
95-
attrs = {
96-
name = "Grafana";
97-
provider = "!KeyOf provider";
98-
policy_engine_mode = "any";
99-
};
100-
}
101-
];
102-
}];
62+
services.authentik.blueprints = [
63+
{
64+
metadata.name = "grafana-oauth";
65+
entries = [
66+
{
67+
model = "authentik_providers_oauth2.oauth2provider";
68+
state = "present";
69+
identifiers.name = "Grafana";
70+
id = "provider";
71+
attrs = {
72+
authentication_flow = "!Find [authentik_flows.flow, [slug, default-authentication-flow]]";
73+
authorization_flow = "!Find [authentik_flows.flow, [slug, default-provider-authorization-explicit-consent]]";
74+
client_type = "confidential";
75+
client_id = "grafana";
76+
client_secret = "secret";
77+
access_code_validity = "minutes=1";
78+
access_token_validity = "minutes=5";
79+
refresh_token_validity = "days=30";
80+
property_mappings = [
81+
"!Find [authentik_providers_oauth2.scopemapping, [scope_name, openid]]"
82+
"!Find [authentik_providers_oauth2.scopemapping, [scope_name, email]]"
83+
"!Find [authentik_providers_oauth2.scopemapping, [scope_name, profile]]"
84+
"!Find [authentik_providers_oauth2.scopemapping, [scope_name, offline_access]]"
85+
];
86+
sub_mode = "hashed_user_id";
87+
include_claims_in_id_token = true;
88+
issuer_mode = "per_provider";
89+
};
90+
}
91+
{
92+
model = "authentik_core.application";
93+
state = "present";
94+
identifiers.slug = "grafana";
95+
id = "grafana";
96+
attrs = {
97+
name = "Grafana";
98+
provider = "!KeyOf provider";
99+
policy_engine_mode = "any";
100+
};
101+
}
102+
];
103+
}
104+
{
105+
metadata.name = "nodered-oauth";
106+
entries = [
107+
{
108+
model = "authentik_providers_oauth2.oauth2provider";
109+
state = "present";
110+
identifiers.name = "Node-RED";
111+
id = "provider";
112+
attrs = {
113+
authentication_flow = "!Find [authentik_flows.flow, [slug, default-authentication-flow]]";
114+
authorization_flow = "!Find [authentik_flows.flow, [slug, default-provider-authorization-explicit-consent]]";
115+
client_type = "confidential";
116+
client_id = "node-red";
117+
client_secret = "secret";
118+
access_code_validity = "minutes=1";
119+
access_token_validity = "minutes=5";
120+
refresh_token_validity = "days=30";
121+
property_mappings = [
122+
"!Find [authentik_providers_oauth2.scopemapping, [scope_name, openid]]"
123+
"!Find [authentik_providers_oauth2.scopemapping, [scope_name, email]]"
124+
"!Find [authentik_providers_oauth2.scopemapping, [scope_name, profile]]"
125+
];
126+
sub_mode = "hashed_user_id";
127+
include_claims_in_id_token = true;
128+
issuer_mode = "per_provider";
129+
};
130+
}
131+
{
132+
model = "authentik_core.application";
133+
state = "present";
134+
identifiers.slug = "node-red";
135+
id = "node-red";
136+
attrs = {
137+
name = "Node-RED";
138+
provider = "!KeyOf provider";
139+
policy_engine_mode = "any";
140+
};
141+
}
142+
];
143+
}
144+
];
103145

104146
profiles.monitoring = {
105147
enable = true;
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
module.exports = {
2+
flowFile: 'flows.json',
3+
flowFilePretty: true,
4+
uiPort: process.env.PORT || 1880,
5+
diagnostics: {
6+
enabled: true,
7+
ui: true,
8+
},
9+
runtimeState: {
10+
enabled: false,
11+
ui: false,
12+
},
13+
logging: {
14+
console: {
15+
level: "warn",
16+
metrics: false,
17+
audit: false
18+
}
19+
},
20+
exportGlobalContextKeys: false,
21+
externalModules: {},
22+
editorTheme: {
23+
palette: {},
24+
projects: {
25+
enabled: false,
26+
workflow: {
27+
mode: "manual"
28+
}
29+
},
30+
codeEditor: {
31+
lib: "monaco",
32+
options: {
33+
}
34+
},
35+
markdownEditor: {
36+
mermaid: {
37+
enabled: true
38+
}
39+
},
40+
},
41+
functionExternalModules: true,
42+
functionTimeout: 0,
43+
functionGlobalContext: {},
44+
debugMaxLength: 1000,
45+
mqttReconnectTime: 15000,
46+
serialReconnectTime: 15000,
47+
adminAuth: {
48+
type: 'strategy',
49+
strategy: {
50+
name: "openidconnect",
51+
label: 'Sign in with authentik',
52+
icon: "fa-cloud",
53+
strategy: require("passport-openidconnect").Strategy,
54+
options: {
55+
issuer: 'https://authentik.adama.lan/application/o/node-red/',
56+
authorizationURL: 'https://authentik.adama.lan/application/o/authorize/',
57+
tokenURL: 'https://authentik.adama.lan/application/o/token/',
58+
userInfoURL: 'https://authentik.adama.lan/application/o/userinfo/',
59+
clientID: 'node-red',
60+
clientSecret: 'secret',
61+
callbackURL: 'https://node-red.adama.lan/auth/strategy/callback/',
62+
scope: ['email', 'profile', 'openid'],
63+
proxy: true,
64+
verify: function (issuer, profile, done) {
65+
done(null, profile)
66+
}
67+
},
68+
},
69+
users: function (user) {
70+
return Promise.resolve({ username: user, permissions: "*" });
71+
}
72+
},
73+
}

nixos-modules/profiles/smarthome.nix

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,11 @@ in
6767
services.node-red = {
6868
enable = true;
6969
withNpmAndGcc = true;
70-
define."logging.console.level" = "warn";
70+
configFile = ./nodered-settings.js;
7171
};
72+
systemd.services.node-red.environment.NODE_PATH = let
73+
pkg = (pkgs.callPackage ../../pkgs/passport-openidconnect {}).package;
74+
in
75+
"${pkg.outPath}/lib/node_modules";
7276
};
7377
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# This file has been generated by node2nix 1.11.1. Do not edit!
2+
3+
{pkgs ? import <nixpkgs> {
4+
inherit system;
5+
}, system ? builtins.currentSystem, nodejs ? pkgs."nodejs_18"}:
6+
7+
let
8+
nodeEnv = import ./node-env.nix {
9+
inherit (pkgs) stdenv lib python2 runCommand writeTextFile writeShellScript;
10+
inherit pkgs nodejs;
11+
libtool = if pkgs.stdenv.isDarwin then pkgs.darwin.cctools else null;
12+
};
13+
in
14+
import ./node-packages.nix {
15+
inherit (pkgs) fetchurl nix-gitignore stdenv lib fetchgit fetchFromGitHub;
16+
inherit nodeEnv;
17+
}

0 commit comments

Comments
 (0)