Closed jamescurtin closed 3 years ago
Hello @jamescurtin , I agree that splitting the config file could be handy in some circumstances. Clearly, access control rules could be in a dedicated file. It'll make even more sense when Authelia have its own set of custom resources for Kubernetes which will definitely come at some point
Splitting the config file is definitely a nice to have for me at the moment and therefore I'm assigning a low priority to that issue. So unless someone provide specs and implement it, it'll wait the stream on Kubernetes custom resources. Stay tuned.
I think the simplest implementation of this that would likely be the most effective is to have --config specify a file, and --config-dir specify a dir. One and only one of these options must be defined.
For config dir it would consider all yml's in a dir, and expect all of them to have root config values. One caveat to this is overlapping config could be an issue.
For example if you wanted session in mysession.yml it would have to contain etc:
session:
domain: example.com
myrules.yml could contain:
access_control:
default_policy: deny
rules:
- domain: public.example.com
policy: bypass
- domain: secure.example.com
policy: one_factor
networks:
- 192.168.1.0/24
- domain: secure.example.com
policy: two_factor
- domain: singlefactor.example.com
policy: one_factor
- domain: "mx2.mail.example.com"
subject: "group:admins"
policy: deny
- domain: "*.example.com"
subject: "group:admins"
policy: two_factor
- domain: dev.example.com
resources:
- "^/groups/dev/.*$"
subject: "group:dev"
policy: two_factor
- domain: dev.example.com
resources:
- "^/users/john/.*$"
subject: "user:john"
policy: two_factor
@jamescurtin this is now implemented! It works by just adding more --config options. They are processed in order, each of them can override settings from all previous ones if they have the same keys.
A bit late to the party, but I had a similar problem. My aim, however, was to split the rules section between domain-specific (site-specific) config folders. The documentation states
If duplicate keys are specified the last one to be specified is the one that takes precedence
and
if you have two files that specify these sections and expect them to merge properly you are asking for trouble
I found the following solution. I hope it may help others with the same problem.
I built on the Go templates mechanism. I included the following snippet in my configuration.yml
:
access_control:
default_policy: deny
rules:
{{- range mustEnv "HOMELAB_AUTHELIA_FRAGMENTS" | split ":" }}
{{- if hasPrefix "rules." (base .) }}
{{- fileContent . | expandenv | nindent 4 }}
{{- end}}
{{- end}}
I also added an environment variable that includes a colon-separated list of all the names of files containing authelia "fragment files": files named *.authelia.fragment
. Of which I only use the ones called rules.authelia.fragment
.
I do the same for the networks
part of the configuration with files named networks.authelia.fragment
and can do the same for any other part of the configuration I wish to make by collecting many site-specific files.
The env. variable HOMELAB_AUTHELIA_FRAGMENTS
is a bit of pain to populate. That's why I also added an override to the entrypoint script for docker compose:
services:
authelia:
image: authelia/authelia:latest
volumes:
- ./config:/config
- ./extend_env_entrypoint.sh:/extend-env-entrypoint.sh
- ./services:/services
entrypoint: ["/extend-env-entrypoint.sh"]
...
This script collects all these names:
#!/usr/bin/env sh
set -eu
set -o pipefail
export HOMELAB_AUTHELIA_FRAGMENTS="$(find /services -name "*.authelia.fragment" | head -c -1 | tr -s "\n" ':' )"
exec /app/entrypoint.sh "$@"
(the call to head -c -1
there is only to remove the trailing newline)
Of course, I also have to map my base path for search to /services
container folder, which is done in the service's volumes
section.
That's it. And so far it works great. All I have to do when adding a new service to my reverse proxy is add a file named rules.authelia.fragment
with the relevant rules configuration for it.
One other thing, thanks so much for all your work. It is a pleasure to work with authelia!
Thank you for the instructions on how to combine multiple configuration files. I would like to save the access_control rules sorted by hosts for more clarity.
The docker-compose.yml looks like this:
version: "3.9"
services:
authelia:
image: authelia/authelia:4.38.9
hostname: authelia
volumes:
- ./etc:/config
- ./var:/var
networks:
- proxy
environment:
- TZ=Europe/Berlin
- AUTHELIA_RULES_FILES=/config/rules.host1.yml:/config/rules.host2.yml
restart: unless-stopped
networks:
proxy:
external:
name: proxy
The access_control section in the configuration.yml looks like this:
access_control:
default_policy: deny
rules:
{{- range mustEnv "AUTHELIA_RULES_FILES" | split ":" }}
{{- if hasPrefix "rules." (base .) }}
{{- fileContent . | expandenv | nindent 4 }}
{{- end}}
{{- end}}
For example, the rules.host1.yml looks like this:
- domain: traefik.local
policy: one_factor
subject:
- group:admin
If I start the container with docker-compose up
, I get the following error message:
[authelia] | time="2024-07-22T14:10:56+02:00" level=error msg="Configuration: failed to load configuration from file path(/config/configuration.yml) source: yaml: line 37: could not find expected ':'"
If I write the content of the rules.host1.yml directly into the configuration.yml, Authelia starts without an error message. Maybe someone sees my mistake and can help me, or is there a better solution for the problem in the meantime?
You can use the authelia config template
command within the context of the container shell to debug it.
Thanks for the tip, now it works. I had an authorization problem with SELinux.
Wouldn't it make sense to implement a possibility that Authelia automatically monitors a config folder and automatically loads the configuration from it?
The current workaround is not very nice, but quite “easy” to implement, so I think that a permanent implementation in Authelia should not be a huge effort or am I wrong?
Regardless, thanks for this great piece of software :)
Thanks for your work on this great project!
I'm believe that it would be valuable to split configuration across multiple files: this would be in addition to the support for storing passwords in environment variables.
The use case is to keep deployment specific parameters (e.g. access control rules) separate from parameters that would be re-used across deployments (e.g. port number, regulation options, etc.)
Ideally, I could structure my project like:
And have the docker-compose file (contrived example, but you get the idea):
What do you think? Because the project users viper, this should be a fairly straightforward addition; would just need to check if the
--config
path was a directory, and if so iterate through the directory contents, using an approach like the one suggested here.