|
|
(17 intermediate revisions by 7 users not shown) |
Line 1: |
Line 1: |
| '''[https://keycloak.org/ Keycloak]''' ([[wikipedia:en:Keycloak]]) is a software for IdM[[category:IdM]]. | | '''[https://keycloak.org/ Keycloak]''' ([[wikipedia:en:Keycloak|Wikipedia]]) is identity and access management software, and can serve as an authentication server for applications (providing support for OpenID Connect, OAuth 2.0, and SAML). |
|
| |
|
| [[Keycloak]] is part of the manual.[[category:manual]]<ref>https://nixos.org/manual/nixos/stable/index.html#module-services-keycloak</ref>
| | For official documentation on Keycloak please consult the [https://nixos.org/manual/nixos/stable/index.html#module-services-keycloak NixOS manual]. |
|
| |
|
| [[Keycloak]] is a package[[category:package]].<ref>https://search.nixos.org/packages?type=packages&query=keycloak</ref>
| | == Setup == |
| | Following configuration will enable a minimal and insecure Keycloak instance for '''testing purpose'''.<syntaxhighlight lang="nix"> |
| | environment.etc."keycloak-database-pass".text = "PWD"; |
| | services.keycloak = { |
| | enable = true; |
| | settings = { |
| | hostname = "localhost"; |
| | http-enabled = true; |
| | hostname-strict-https = false; |
| | }; |
| | database.passwordFile = "/etc/keycloak-database-pass"; |
| | }; |
| | </syntaxhighlight>After applying the configuration the Keycloak management interface will be available at http://localhost. Login with username <code>admin</code> and password <code>changeme</code>. |
|
| |
|
| [[Keycloak]] is a service[[category:service]].<ref>https://search.nixos.org/options?query=keycloak</ref>
| | == Configuration == |
|
| |
|
| [[Keycloak]] is written in [[Java]][[category:java]].
| | === Importing realms === |
| | {{Note|The module is not yet part of the latest NixOS stable release and will be available with version 24.11.}}Using the realmFiles option, it is possible provision a realm from a JSON file or previous JSON export.<syntaxhighlight lang="nix"> |
| | { ... }: let |
|
| |
|
| [[Keycloak]] is maintained by [[Red Hat]][[category:Red Hat]]. | | realm = { |
| | realm = "OIDCDemo"; |
| | enabled = true; |
| | clients = [{ |
| | clientId = "mydemo"; |
| | rootUrl = "http://localhost:8080"; |
| | }]; |
| | users = [{ |
| | enabled = true; |
| | firstName = "Christian"; |
| | lastName = "Bauer"; |
| | username = "cbauer"; |
| | email = "cbauer@localhost"; |
| | credentials = [{ |
| | type = "password"; |
| | temporary = false; |
| | value = "changeme"; |
| | }]; |
| | }]; |
| | }; |
|
| |
|
| == known problems ==
| | in { |
|
| |
|
| === dependencies for X are causing problems === | | services.keycloak = { |
| | realmFiles = [ |
| | (pkgs.writeText "OIDCDemo.json" (builtins.toJSON realm)) |
| | ]; |
| | }; |
|
| |
|
| ; problem:
| | } |
| | </syntaxhighlight> |
| | == Tips and tricks == |
|
| |
|
| : <code>nixos-rebuild switch</code>
| | === Installation in subdirectory === |
| <pre>
| | Keycloak may be installed in a subdirectory of a domain. Thus you don't need to configure and expose a subdomain. For example with the following configuration, remember to edit <code>domain.tld</code>, reflecting your used domain. |
| building Nix...
| |
| building the system configuration...
| |
| these derivations will be built:
| |
| /nix/store/608nwzjmrnddh3zib749lml0k1k9rvhw-gtk+-2.24.32.drv
| |
| /nix/store/672ykfqmhcfp0lwcck13z0mbmkdhxz78-python3.9-pycairo-1.20.1.drv
| |
| /nix/store/k4xdln4fql2vnd2psksh1x98y4gk8f49-python3.9-pygobject-3.40.1.drv
| |
| /nix/store/4zamf3w9zkbf5r62pf1lc5sf6hwc77ks-tracker-3.1.1.drv
| |
| /nix/store/sj08y9hp5w8i1s6zhpc0xcc5bgypdn24-gtk+3-3.24.30.drv
| |
| /nix/store/dinml75y8q561ss98gbqa1gmj53wxz5g-adoptopenjdk-hotspot-bin-11.0.11.drv
| |
| /nix/store/m889f14h5qm2wx72z53cd88n4n1basly-openjdk-headless-11.0.12+7.drv
| |
| /nix/store/8bs98qvxync34ynd88f22vzm5fzynr27-gradle.properties.drv
| |
| /nix/store/i9y53zmjj0s8wl3cm54l9kqpjz2pp8a8-gradle-5.6.4.drv
| |
| /nix/store/pkvksaw53f6ybzqr7rsr6xw91sxj2jms-openjfx-modular-sdk-15.0.1+1.drv
| |
| /nix/store/vq2c73hr83ban0037g4fld797y5326z2-adoptopenjdk-hotspot-bin-15.0.2.drv
| |
| /nix/store/81br4p5nx2b9728pd7wnmh19f179i931-openjdk-16+36.drv
| |
| /nix/store/ggfcd8q52s6zv2fvfvpvifwr3l358972-keycloak-15.0.2.drv
| |
| /nix/store/1k9b87hh8h3mmlqkj50kvlm396s4f1bx-system-path.drv
| |
| /nix/store/y0wasv0dfkgygqsnmh86vhlw4rnyzr5n-dbus-1.drv
| |
| /nix/store/zk907kz6s1vqbmrdm1z8cqmd5s1rsnx0-unit-dbus.service.drv
| |
| /nix/store/4pfm2mky74l68mccrbaa8ldrnp3lj1h1-user-units.drv
| |
| /nix/store/7ydxnzracdsfj6y6l5bi03a2i17hpiyi-unit-polkit.service.drv
| |
| /nix/store/a4jr0hh8lmajrmiqqqb79dpkgx90xfkf-unit-dbus.service.drv
| |
| /nix/store/ffipfpz3v5snqmwizmas7cc3s8ida48q-unit-systemd-fsck-.service.drv
| |
| /nix/store/k0f99srj3g5gizgpkv2qrc63dgmvn2yf-keycloak-config.drv
| |
| /nix/store/rj4alwnw2m96b7zf2a4w8wkisfyxyv26-keycloak-start-pre.drv
| |
| /nix/store/qyq9ai27sl7wq27v4hjh9imjwsnl6h6l-unit-keycloak.service.drv
| |
| /nix/store/bcb0if33acwhl4rp1x9zn5mb3p3k2mqb-system-units.drv
| |
| /nix/store/sad248mmajrxyy1069l9gh83li6skxl1-etc.drv
| |
| /nix/store/vfzd5z4fn1k6q46bv7lbk4yqhzfqg2a0-nixos-system-nixos-21.11pre322478.e4ef597edfd.drv
| |
| building '/nix/store/608nwzjmrnddh3zib749lml0k1k9rvhw-gtk+-2.24.32.drv'...
| |
| unpacking sources
| |
| unpacking source archive /nix/store/7qbmp81hzfwlq8vcad7bs9kg4x809r4w-gtk+-2.24.32.tar.xz
| |
| source root is gtk+-2.24.32
| |
| setting SOURCE_DATE_EPOCH to timestamp 1515447963 of file gtk+-2.24.32/README
| |
| patching sources
| |
| applying patch /nix/store/pri6h73ac1q076pb858jarpnh5lgd0p6-2.0-immodules.cache.patch
| |
| patching file gtk/gtkrc.c
| |
| Hunk #1 succeeded at 445 with fuzz 1.
| |
| applying patch /nix/store/0i5i9mj0n4nry46qvzlmi6h1k9d3pbcn-gtk2-theme-paths.patch
| |
| patching file gtk/gtkrc.c
| |
| Hunk #1 succeeded at 826 (offset 18 lines).
| |
| Hunk #2 succeeded at 850 (offset 18 lines).
| |
| configuring
| |
| fixing libtool script ./ltmain.sh
| |
| configure flags: --disable-static --disable-dependency-tracking --prefix=/nix/store/700y8fq2h0na1n031splldln1m2cyc80-gtk+-2.24.32 --bindir=/nix/store/pb32w8jfn2949rl1ws65ipirsgy0g1wj-gtk+-2.24.32-dev/bin --sbindir=/nix/store/pb32w8jfn2949rl1ws65ipirsgy0g1wj-gtk+-2.24.32-dev/sbin --includedir=/nix/store/pb32w8jfn2949rl1ws65ipirsgy0g1wj-gtk+-2.24.32-dev/include --oldincludedir=/nix/store/pb32w8jfn2949rl1ws65ipirsgy0g1wj-gtk+-2.24.32-dev/include --mandir=/nix/store/pb32w8jfn2949rl1ws65ipirsgy0g1wj-gtk+-2.24.32-dev/share/man --infodir=/nix/store/pb32w8jfn2949rl1ws65ipirsgy0g1wj-gtk+-2.24.32-dev/share/info --docdir=/nix/store/700y8fq2h0na1n031splldln1m2cyc80-gtk+-2.24.32/share/doc/gtk+ --libdir=/nix/store/700y8fq2h0na1n031splldln1m2cyc80-gtk+-2.24.32/lib --libexecdir=/nix/store/700y8fq2h0na1n031splldln1m2cyc80-gtk+-2.24.32/libexec --localedir=/nix/store/700y8fq2h0na1n031splldln1m2cyc80-gtk+-2.24.32/share/locale --with-gdktarget=x11 --with-xinput=yes
| |
| checking for a BSD-compatible install... /nix/store/xyn0240zrpprnspg3n0fi8c8aw5bq0mr-coreutils-8.32/bin/install -c
| |
| checking whether build environment is sane... yes
| |
| checking for a thread-safe mkdir -p... /nix/store/xyn0240zrpprnspg3n0fi8c8aw5bq0mr-coreutils-8.32/bin/mkdir -p
| |
| checking for gawk... gawk
| |
| checking whether make sets $(MAKE)... yes
| |
| checking whether make supports nested variables... yes
| |
| checking whether make supports nested variables... (cached) yes
| |
| checking build system type... x86_64-pc-linux-gnu
| |
| checking host system type... x86_64-pc-linux-gnu
| |
| checking for native Win32... no
| |
| checking for gcc... gcc
| |
| checking whether the C compiler works... yes
| |
| checking for C compiler default output file name... a.out
| |
| checking for suffix of executables...
| |
| checking whether we are cross compiling... no
| |
| checking for suffix of object files... o
| |
| checking whether we are using the GNU C compiler... yes
| |
| checking whether gcc accepts -g... yes
| |
| checking for gcc option to accept ISO C89... none needed
| |
| checking whether gcc understands -c and -o together... yes
| |
| checking for style of include used by make... GNU
| |
| checking dependency style of gcc... none
| |
| checking whether we are using the GNU C++ compiler... yes
| |
| checking whether g++ accepts -g... yes
| |
| checking dependency style of g++... none
| |
| checking how to print strings... printf
| |
| checking for a sed that does not truncate output... /nix/store/dy4ylp9439la4lq35ah2mj80fi87pk4w-gnused-4.8/bin/sed
| |
| checking for grep that handles long lines and -e... /nix/store/xxgddhdi57bbgd1yxza44plq6krjmiz1-gnugrep-3.6/bin/grep
| |
| checking for egrep... /nix/store/xxgddhdi57bbgd1yxza44plq6krjmiz1-gnugrep-3.6/bin/grep -E
| |
| checking for fgrep... /nix/store/xxgddhdi57bbgd1yxza44plq6krjmiz1-gnugrep-3.6/bin/grep -F
| |
| checking for ld used by gcc... ld
| |
| checking if the linker (ld) is GNU ld... yes
| |
| checking for BSD- or MS-compatible name lister (nm)... nm
| |
| checking the name lister (nm) interface... BSD nm
| |
| checking whether ln -s works... yes
| |
| checking the maximum length of command line arguments... 1572864
| |
| checking how to convert x86_64-pc-linux-gnu file names to x86_64-pc-linux-gnu format... func_convert_file_noop
| |
| checking how to convert x86_64-pc-linux-gnu file names to toolchain format... func_convert_file_noop
| |
| checking for ld option to reload object files... -r
| |
| checking for objdump... objdump
| |
| checking how to recognize dependent libraries... (cached) pass_all
| |
| checking for dlltool... dlltool
| |
| checking how to associate runtime and link libraries... printf %s\n
| |
| checking for archiver @FILE support... @
| |
| checking for strip... strip
| |
| checking for ranlib... ranlib
| |
| checking command to parse nm output from gcc object... ok
| |
| checking for sysroot... no
| |
| checking for a working dd... /nix/store/xyn0240zrpprnspg3n0fi8c8aw5bq0mr-coreutils-8.32/bin/dd
| |
| checking how to truncate binary pipes... /nix/store/xyn0240zrpprnspg3n0fi8c8aw5bq0mr-coreutils-8.32/bin/dd bs=4096 count=1
| |
| ./configure: line 8043: /usr/bin/file: No such file or directory
| |
| checking for mt... no
| |
| checking if : is a manifest tool... no
| |
| checking how to run the C preprocessor... gcc -E
| |
| checking for ANSI C header files... yes
| |
| checking for sys/types.h... yes
| |
| checking for sys/stat.h... yes
| |
| checking for stdlib.h... yes
| |
| checking for string.h... yes
| |
| checking for memory.h... yes
| |
| checking for strings.h... yes
| |
| checking for inttypes.h... yes
| |
| checking for stdint.h... yes
| |
| checking for unistd.h... yes
| |
| checking for dlfcn.h... yes
| |
| checking for objdir... .libs
| |
| checking if gcc supports -fno-rtti -fno-exceptions... no
| |
| checking for gcc option to produce PIC... -fPIC -DPIC
| |
| checking if gcc PIC flag -fPIC -DPIC works... yes
| |
| checking if gcc static flag -static works... no
| |
| checking if gcc supports -c -o file.o... yes
| |
| checking if gcc supports -c -o file.o... (cached) yes
| |
| checking whether the gcc linker (ld) supports shared libraries... yes
| |
| checking whether -lc should be explicitly linked in... no
| |
| checking dynamic linker characteristics... GNU/Linux ld.so
| |
| checking how to hardcode library paths into programs... immediate
| |
| checking whether stripping libraries is possible... yes
| |
| checking if libtool supports shared libraries... yes
| |
| checking whether to build shared libraries... yes
| |
| checking whether to build static libraries... no
| |
| checking how to run the C++ preprocessor... g++ -E
| |
| checking for ld used by g++... ld
| |
| checking if the linker (ld) is GNU ld... yes
| |
| checking whether the g++ linker (ld) supports shared libraries... yes
| |
| checking for g++ option to produce PIC... -fPIC -DPIC
| |
| checking if g++ PIC flag -fPIC -DPIC works... yes
| |
| checking if g++ static flag -static works... no
| |
| checking if g++ supports -c -o file.o... yes
| |
| checking if g++ supports -c -o file.o... (cached) yes
| |
| checking whether the g++ linker (ld) supports shared libraries... yes
| |
| checking dynamic linker characteristics... (cached) GNU/Linux ld.so
| |
| checking how to hardcode library paths into programs... immediate
| |
| configure: creating ./config.lt
| |
| config.lt: creating libtool
| |
| checking for special C compiler options needed for large files... no
| |
| checking for _FILE_OFFSET_BITS value needed for large files... no
| |
| checking dependency style of gcc... none
| |
| checking for nm... /nix/store/a4mmjm3bblxwp8h53bcfx3dly80ib0ba-binutils-2.35.1/bin/nm
| |
| checking whether to enable maintainer-specific portions of Makefiles... yes
| |
| checking for some Win32 platform... no
| |
| checking whether build environment is sane... yes
| |
| checking for library containing strerror... none required
| |
| checking whether make sets $(MAKE)... (cached) yes
| |
| checking pkg-config is at least version 0.9.0... yes
| |
| checking for BASE_DEPENDENCIES... yes
| |
| checking for CAIRO_BACKEND... no
| |
| configure: error: Package requirements (cairo-xlib >= 1.6) were not met:
| |
|
| |
|
| No package 'cairo-xlib' found
| | {{file|/etc/nixos/configuration.nix|nix|<nowiki> |
| | { |
|
| |
|
| Consider adjusting the PKG_CONFIG_PATH environment variable if you
| | services.nginx = { |
| installed software in a non-standard prefix.
| | enable = true; |
|
| |
|
| Alternatively, you may set the environment variables CAIRO_BACKEND_CFLAGS
| | # enable recommended settings |
| and CAIRO_BACKEND_LIBS to avoid the need to call pkg-config.
| | recommendedGzipSettings = true; |
| See the pkg-config man page for more details.
| | recommendedOptimisation = true; |
| builder for '/nix/store/608nwzjmrnddh3zib749lml0k1k9rvhw-gtk+-2.24.32.drv' failed with exit code 1
| | recommendedTlsSettings = true; |
| cannot build derivation '/nix/store/pkvksaw53f6ybzqr7rsr6xw91sxj2jms-openjfx-modular-sdk-15.0.1+1.drv': 1 dependencies couldn't be built
| | recommendedProxySettings = true; |
| building '/nix/store/672ykfqmhcfp0lwcck13z0mbmkdhxz78-python3.9-pycairo-1.20.1.drv'...
| |
| cannot build derivation '/nix/store/81br4p5nx2b9728pd7wnmh19f179i931-openjdk-16+36.drv': 1 dependencies couldn't be built
| |
| cannot build derivation '/nix/store/ggfcd8q52s6zv2fvfvpvifwr3l358972-keycloak-15.0.2.drv': 1 dependencies couldn't be built
| |
| cannot build derivation '/nix/store/1k9b87hh8h3mmlqkj50kvlm396s4f1bx-system-path.drv': 1 dependencies couldn't be built
| |
| cannot build derivation '/nix/store/qyq9ai27sl7wq27v4hjh9imjwsnl6h6l-unit-keycloak.service.drv': 1 dependencies couldn't be built
| |
| cannot build derivation '/nix/store/vfzd5z4fn1k6q46bv7lbk4yqhzfqg2a0-nixos-system-nixos-21.11pre322478.e4ef597edfd.drv': 1 dependencies couldn't be built
| |
| error: build of '/nix/store/vfzd5z4fn1k6q46bv7lbk4yqhzfqg2a0-nixos-system-nixos-21.11pre322478.e4ef597edfd.drv' failed
| |
| </pre>
| |
|
| |
|
| ; solution: | | virtualHosts = { |
| | "domain.tld" = { |
| | forceSSL = true; |
| | enableACME = true; |
| | locations = { |
| | "/cloak/" = { |
| | proxyPass = "http://localhost:${toString config.services.keycloak.settings.http-port}/cloak/"; |
| | }; |
| | }; |
| | }; |
| | }; |
| | }; |
|
| |
|
| Probably you should not have a need for libraries for [[X]] on a system that just provides a service for [[IdM]] (like [[Keycloak]]).
| | services.postgresql.enable = true; |
|
| |
|
| : <code>nano /etc/nixos/configuration.nix</code>
| | services.keycloak = { |
| <pre>
| | enable = true; |
| { config, pkgs, ... }: | | |
| | database = { |
| | type = "postgresql"; |
| | createLocally = true; |
| | |
| | username = "keycloak"; |
| | passwordFile = "/etc/nixos/secrets/keycloak_psql_pass"; |
| | }; |
| | |
| | settings = { |
| | hostname = "domain.tld"; |
| | http-relative-path = "/cloak"; |
| | http-port = 38080; |
| | proxy = "passthrough"; |
| | http-enabled = true; |
| | }; |
| | }; |
|
| |
|
| {
| |
| </pre>
| |
| <pre></pre>
| |
| <pre>
| |
| environment.noXlibs = false;
| |
| </pre>
| |
| <pre></pre>
| |
| <pre>
| |
| } | | } |
| </pre> | | </nowiki>}} |
| | |
| | === Keycloak themes on NixOS === |
| | You need to create a package for your custom theme and configure the keycloak service to use it |
| | |
| | Here is a what a basic theme will look like : |
| | |
| | - configuration.nix |
| | - keycloak |
| | - custom_theme |
| | - login |
| | - resources |
| | - css |
| | - custom.css |
| | - theme.properties |
| | - default.nix <- set of packages to be imported in your configuration.nix |
| | - keycloak_custom_theme.nix <- package for your theme |
| | |
| | ==== Create a theme ==== |
| | |
| | {{file|custom.css|css|<nowiki> |
| | body { |
| | background: red; |
| | color: blue; |
| | } |
| | </nowiki>}} |
| | |
| | {{file|theme.properties|bash|<nowiki> |
| | parent=base |
| | import=common/keycloak |
| | styles=css/custom.css |
| | </nowiki>}} |
| | |
| | ==== Create a package ==== |
| | {{file|keycloak_custom_theme.nix|nix|<nowiki> |
| | { stdenv }: |
| | stdenv.mkDerivation rec { |
| | name = "keycloak_custom_theme"; |
| | version = "1.0"; |
| | |
| | src = ./keycloak_custom_theme; |
| | |
| | nativeBuildInputs = [ ]; |
| | buildInputs = [ ]; |
| | |
| | installPhase = '' |
| | mkdir -p $out |
| | cp -a login $out |
| | ''; |
| | } |
| | </nowiki>}} |
| | |
| | ==== Create a packages set ==== |
| | |
| | {{file|default.nix|nix|<nowiki> |
| | {pkgs, ...}: let |
| | callPackage = pkgs.callPackage; |
| | in { |
| | nixpkgs.overlays = [(final: prev: { |
| | custom_keycloak_themes = { |
| | custom = callPackage ./keycloak_custom_theme.nix {}; |
| | }; |
| | })]; |
| | } |
| | </nowiki>}} |
|
| |
|
| : <code>nixos-rebuild switch</code>
| | ==== Configure your keycloak service ==== |
| <pre>
| | {{file|configuration.nix|nix|<nowiki> |
| </pre> | | { config, pkgs, lib, ... }: |
| | { |
| | imports = |
| | [ # Include the results of the hardware scan. |
| | ./hardware-configuration.nix |
| | ./keycloak |
| | ]; |
| | ... |
| | environment.systemPackages = with pkgs; [ |
| | ... |
| | # authentication requires |
| | keycloak |
| | custom_keycloak_themes.agatha |
| | ]; |
| | ... |
| | services.keycloak = { |
| | enable = true; |
| | themes = with pkgs ; { |
| | custom = custom_keycloak_themes.custom; |
| | }; |
| | ... |
| | } |
| | </nowiki>}} |
|
| |
|
| == References ==
| | [[Category:Server]] |
| <references />
| | [[Category:Security]] |
| | [[Category:NixOS Manual]] |
Keycloak (Wikipedia) is identity and access management software, and can serve as an authentication server for applications (providing support for OpenID Connect, OAuth 2.0, and SAML).
For official documentation on Keycloak please consult the NixOS manual.
Setup
Following configuration will enable a minimal and insecure Keycloak instance for testing purpose.
environment.etc."keycloak-database-pass".text = "PWD";
services.keycloak = {
enable = true;
settings = {
hostname = "localhost";
http-enabled = true;
hostname-strict-https = false;
};
database.passwordFile = "/etc/keycloak-database-pass";
};
After applying the configuration the Keycloak management interface will be available at http://localhost. Login with username admin
and password changeme
.
Configuration
Importing realms
Note: The module is not yet part of the latest NixOS stable release and will be available with version 24.11.
Using the realmFiles option, it is possible provision a realm from a JSON file or previous JSON export.
{ ... }: let
realm = {
realm = "OIDCDemo";
enabled = true;
clients = [{
clientId = "mydemo";
rootUrl = "http://localhost:8080";
}];
users = [{
enabled = true;
firstName = "Christian";
lastName = "Bauer";
username = "cbauer";
email = "cbauer@localhost";
credentials = [{
type = "password";
temporary = false;
value = "changeme";
}];
}];
};
in {
services.keycloak = {
realmFiles = [
(pkgs.writeText "OIDCDemo.json" (builtins.toJSON realm))
];
};
}
Tips and tricks
Installation in subdirectory
Keycloak may be installed in a subdirectory of a domain. Thus you don't need to configure and expose a subdomain. For example with the following configuration, remember to edit domain.tld
, reflecting your used domain.
/etc/nixos/configuration.nix
{
services.nginx = {
enable = true;
# enable recommended settings
recommendedGzipSettings = true;
recommendedOptimisation = true;
recommendedTlsSettings = true;
recommendedProxySettings = true;
virtualHosts = {
"domain.tld" = {
forceSSL = true;
enableACME = true;
locations = {
"/cloak/" = {
proxyPass = "http://localhost:${toString config.services.keycloak.settings.http-port}/cloak/";
};
};
};
};
};
services.postgresql.enable = true;
services.keycloak = {
enable = true;
database = {
type = "postgresql";
createLocally = true;
username = "keycloak";
passwordFile = "/etc/nixos/secrets/keycloak_psql_pass";
};
settings = {
hostname = "domain.tld";
http-relative-path = "/cloak";
http-port = 38080;
proxy = "passthrough";
http-enabled = true;
};
};
}
Keycloak themes on NixOS
You need to create a package for your custom theme and configure the keycloak service to use it
Here is a what a basic theme will look like :
- configuration.nix
- keycloak
- custom_theme
- login
- resources
- css
- custom.css
- theme.properties
- default.nix <- set of packages to be imported in your configuration.nix
- keycloak_custom_theme.nix <- package for your theme
Create a theme
custom.css
body {
background: red;
color: blue;
}
theme.properties
parent=base
import=common/keycloak
styles=css/custom.css
Create a package
keycloak_custom_theme.nix
{ stdenv }:
stdenv.mkDerivation rec {
name = "keycloak_custom_theme";
version = "1.0";
src = ./keycloak_custom_theme;
nativeBuildInputs = [ ];
buildInputs = [ ];
installPhase = ''
mkdir -p $out
cp -a login $out
'';
}
Create a packages set
default.nix
{pkgs, ...}: let
callPackage = pkgs.callPackage;
in {
nixpkgs.overlays = [(final: prev: {
custom_keycloak_themes = {
custom = callPackage ./keycloak_custom_theme.nix {};
};
})];
}
Configure your keycloak service
configuration.nix
{ config, pkgs, lib, ... }:
{
imports =
[ # Include the results of the hardware scan.
./hardware-configuration.nix
./keycloak
];
...
environment.systemPackages = with pkgs; [
...
# authentication requires
keycloak
custom_keycloak_themes.agatha
];
...
services.keycloak = {
enable = true;
themes = with pkgs ; {
custom = custom_keycloak_themes.custom;
};
...
}