diff --git a/.buildkite/deployment.sh b/.buildkite/deployment.sh index 53bc2b1c0..d96221ae9 100755 --- a/.buildkite/deployment.sh +++ b/.buildkite/deployment.sh @@ -61,11 +61,4 @@ steps: agents: upload: "fast" if: build.tag != null - - - label: ":book: Deploy Documentation" - command: "syncdoc.sh" - depends_on: ~ - agents: - upload: "fast" - if: build.branch == "master" -EOF \ No newline at end of file +EOF diff --git a/.buildkite/steps/syncdoc.sh b/.buildkite/steps/syncdoc.sh deleted file mode 100755 index 67d4d17cb..000000000 --- a/.buildkite/steps/syncdoc.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env bash - -set -e - -rm -rf authelia -git clone git@github.com:authelia/authelia.git --single-branch --branch gh-pages - -pushd docs -bundle install -bundle exec jekyll build -d ../authelia -popd - -COMMIT=$(git show -s --format=%h) - -pushd authelia -git config user.name "Authelia[bot]" -git config user.email "autheliabot@gmail.com" - -git status | grep "nothing to commit" && exit -git add -A -git commit -m "Synchronize docs of commit: ${COMMIT}" -git push -popd - -rm -rf authelia diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 87dd83e77..899f94db9 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -2,7 +2,7 @@ blank_issues_enabled: false contact_links: - name: Documentation - url: https://www.authelia.com/docs/ + url: https://www.authelia.com/ about: Read the Documentation - name: Matrix url: https://matrix.to/#/#community:authelia.com diff --git a/.renovaterc b/.renovaterc index fa26dd983..09fe00a98 100644 --- a/.renovaterc +++ b/.renovaterc @@ -4,6 +4,9 @@ ":semanticCommitTypeAll(build)", ":separatePatchReleases" ], + "ignorePaths": [ + "docs/**" + ], "ignorePresets": [ ":combinePatchMinorReleases", "helpers:disableTypesNodeMajor", @@ -58,4 +61,4 @@ "gomodTidy", "gomodNoMassage" ] -} \ No newline at end of file +} diff --git a/.yamllint.yml b/.yamllint.yml index 89675cfa5..3d31542b4 100644 --- a/.yamllint.yml +++ b/.yamllint.yml @@ -2,6 +2,7 @@ extends: default ignore: | + docs/pnpm-lock.yaml internal/configuration/test_resources/config_bad_quoting.yml web/pnpm-lock.yaml web/node_modules/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 886ac4104..1b23c8aaf 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,7 +1,7 @@ # Contributing -Anybody willing to contribute to the project either with code, documentation, security reviews or whatever, are very -welcome to create or review pull requests and take part in discussions in any of our public +Anybody willing to contribute to the project either with code, documentation, security reviews or whatever, are very +welcome to create or review pull requests and take part in discussions in any of our public [chat rooms](./README.md#contact-options). It's also possible to contribute financially in order to support the community. @@ -15,11 +15,13 @@ If you've found a **bug** or have a **feature request** then please create an is ## Code If you would like to fix a bug or implement a feature, please fork the repository and create a Pull Request. -More information on getting set up locally can be found [here](https://www.authelia.com/docs/contributing/). +More information on getting set up locally can be found in the +[Development Contribution](https://www.authelia.com/contributing/development/introduction/) documentation. -Before you start any Pull Request, it's recommended that you create an issue to discuss first if you have any doubts about requirement or implementation. -That way you can be sure that the maintainer(s) agree on what to change and how, and you can hopefully get a quick merge afterwards. -Also, let the maintainers know that you plan to work on a particular issue so that no one else starts any duplicate work. +Before you start any Pull Request, it's recommended that you create an issue to discuss first if you have any doubts +about requirement or implementation. That way you can be sure that the maintainer(s) agree on what to change and how, +and you can hopefully get a quick merge afterwards. Also, let the maintainers know that you plan to work on a particular +issue so that no one else starts any duplicate work. Pull Requests can only be merged once all status checks are green, which means `authelia-scripts --log-level debug ci` passes, and coverage does not regress. @@ -37,7 +39,7 @@ Read more about this in the [GitHub docs, Re-requesting a review](https://docs.g ## Collaboration with maintainers -Sometimes the codebase can be a challenge to navigate, especially for a first-time contributor. We don't want you +Sometimes the codebase can be a challenge to navigate, especially for a first-time contributor. We don't want you spending an hour trying to work out something that would take us only a minute to explain. If you'd like some help getting started we have several [contact options](./README.md#contact-options) available. diff --git a/README.md b/README.md index 086e89ebd..e4004c4f6 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@

- +

[![Build](https://img.shields.io/buildkite/d6543d3ece3433f46dbe5fd9fcfaf1f68a6dbc48eb1048bc22/master?logo=buildkite&style=flat-square&color=brightgreen)](https://buildkite.com/authelia/authelia) @@ -20,12 +20,12 @@ sign-on (SSO) for your applications via a web portal. It acts as a companion for [Traefik], [caddy] or [HAProxy] to let them know whether requests should either be allowed or redirected to Authelia's portal for authentication. -Documentation is available at https://www.authelia.com/docs. +Documentation is available at [https://www.authelia.com/](https://www.authelia.com/). The following is a simple diagram of the architecture:

- +

**Authelia** can be installed as a standalone service from the [AUR](https://aur.archlinux.org/packages/authelia/), @@ -36,15 +36,15 @@ The following is a simple diagram of the architecture: the Helm [Chart](https://charts.authelia.com) (beta) leveraging ingress controllers and ingress configurations.

- - + +

Here is what Authelia's portal looks like:

- - + +

## Features summary @@ -52,11 +52,11 @@ Here is what Authelia's portal looks like: This is a list of the key features of Authelia: * Several second factor methods: - * **[Security Keys](https://www.authelia.com/docs/features/2fa/security-key)** that support [FIDO2] [Webauthn] - with devices like a [YubiKey]. - * **[Time-based One-Time password](https://www.authelia.com/docs/features/2fa/one-time-password)** + * **[Security Keys](https://www.authelia.com/overview/authentication/webauthn-security-key/)** that support + [FIDO2] [Webauthn] with devices like a [YubiKey]. + * **[Time-based One-Time password](https://www.authelia.com/overview/authentication/one-time-password/)** with compatible authenticator applications. - * **[Mobile Push Notifications](https://www.authelia.com/docs/features/2fa/push-notifications)** + * **[Mobile Push Notifications](https://www.authelia.com/overview/authentication/push-notification/)** with [Duo](https://duo.com/). * Password reset with identity verification using email confirmation. * Access restriction after too many invalid authentication attempts. @@ -78,11 +78,11 @@ This is a list of the key features of Authelia: [Traefik Kubernetes Ingress](https://doc.traefik.io/traefik/providers/kubernetes-crd/) Kubernetes ingress controllers out of the box. * Beta support for installing via Helm using our [Charts](https://charts.authelia.com). -* Beta support for [OpenID Connect](https://www.authelia.com/docs/configuration/identity-providers/oidc.html). +* Beta support for [OpenID Connect](https://www.authelia.com/roadmap/active/openid-connect/). -For more details about the features, follow [Features](https://www.authelia.com/docs/features/). +For more details take a look at the [Overview](https://www.authelia.com/overview/prologue/introduction/). -If you want to know more about the roadmap, follow [Roadmap](https://www.authelia.com/docs/roadmap). +If you want to know more about the roadmap, follow [Roadmap](https://www.authelia.com/roadmap). ## Proxy support @@ -90,33 +90,36 @@ Authelia works in combination with [nginx], [Traefik], [caddy] or [HAProxy]. It Docker or on top of [Kubernetes].

- - - - - + + + + +

***Help Wanted:*** Assistance would be appreciated in getting Authelia working with [Envoy](https://www.envoyproxy.io/).

- +

## Getting Started +See the [Get Started Guide](https://www.authelia.com/integration/prologue/get-started/) or one of the curated examples +below. + ### docker-compose The `docker-compose` bundles act as a starting point for anyone wanting to see Authelia in action. You will have to customize them to your needs as they come with self-signed certificates. -#### [Local](https://www.authelia.com/docs/getting-started) +#### [Local](https://www.authelia.com/integration/deployment/docker/#local) The Local compose bundle is intended to test Authelia without worrying about configuration. It's meant to be used for scenarios where the server is not be exposed to the internet. Domains will be defined in the local hosts file and self-signed certificates will be utilised. -#### [Lite](https://www.authelia.com/docs/deployment/deployment-lite) +#### [Lite](https://www.authelia.com/integration/deployment/docker/#lite) The Lite compose bundle is intended for scenarios where the server will be exposed to the internet, domains and DNS will need to be setup accordingly and certificates will be generated through LetsEncrypt. The Lite element refers to minimal external dependencies; File based user storage, SQLite based configuration storage. In this configuration, the service @@ -140,8 +143,8 @@ This guide will show you how to deploy it on bare metal as well as on Authelia takes security very seriously. If you discover a vulnerability in Authelia, please see our [Security Policy](https://github.com/authelia/authelia/security/policy). -For more information about [security](https://www.authelia.com/docs/security/) related matters, please read -[the documentation](https://www.authelia.com/docs/security/). +For more information about [security](https://www.authelia.com/information/security/) related matters, please read +[the documentation](https://www.authelia.com/information/security/). ## Contact Options @@ -345,22 +348,17 @@ Companies contributing to Authelia will have a specical mention below. [[Become #### Balto -Thank you to [Balto Balto](https://www.getbalto.com/) for -hosting our apt repository. - -#### Digital Ocean - -Thank you to [Digital Ocean DigitalOcean](https://www.digitalocean.com/?from=Authelia) for -contributing on OpenCollective. +Thank you to [Balto Balto](https://www.getbalto.com/) +for hosting our apt repository. #### JetBrains -Thank you to [JetBrains JetBrains](https://www.jetbrains.com/?from=Authelia) +Thank you to [JetBrains JetBrains](https://www.jetbrains.com/?from=Authelia) for providing us with free licenses to their great tools. -* [IDEA IDEA](http://www.jetbrains.com/idea/) -* [GoLand GoLand](http://www.jetbrains.com/go/) -* [WebStorm WebStorm](http://www.jetbrains.com/webstorm/) +* [IDEA IDEA](http://www.jetbrains.com/idea/) +* [GoLand GoLand](http://www.jetbrains.com/go/) +* [WebStorm WebStorm](http://www.jetbrains.com/webstorm/) ## License diff --git a/SECURITY.md b/SECURITY.md index 783a2d701..6324e796c 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -2,20 +2,20 @@ ## Prologue -Authelia takes security very seriously. We follow the rule of +Authelia takes security very seriously. We follow the rule of [responsible disclosure](https://en.wikipedia.org/wiki/Responsible_disclosure), and we urge our community to do so as well instead of making the vulnerability public. This allows time for the security issue to be patched quickly. -If you discover a vulnerability in Authelia, please first contact one of the maintainers privately as described in the -[contact options](#contact-options) below. +If you discover a vulnerability in Authelia, please first contact one of the maintainers privately as described in the +[contact options](#contact-options) below. We urge you not to disclose the bug publicly at least until we've had a -reasonable chance to fix it, and to clearly communicate any public disclosure timeline in your initial contact with us. +reasonable chance to fix it, and to clearly communicate any public disclosure timeline in your initial contact with us. If you do not have a particular public disclosure timeline, we will clearly communicate ours as we publish security -advisories. +advisories. -For more information about [security](https://www.authelia.com/docs/security/) related matters, please read -[the documentation](https://www.authelia.com/docs/security/). +For more information about [security](https://www.authelia.com/information/security/) related matters, please read +[the documentation](https://www.authelia.com/information/security/). ## Contact Options @@ -25,7 +25,7 @@ privately which is described in each available contact method. The methods inclu ## Credit -Users who report bugs will optionally be creditted for the discovery. Both in the [security advisory] and in our +Users who report bugs will optionally be credited for the discovery. Both in the [security advisory] and in our [all contributors](./README.md#contribute) configuration/documentation. ## Process @@ -40,8 +40,8 @@ Users who report bugs will optionally be creditted for the discovery. Both in th ## Help Wanted -We are actively looking for sponsorship to obtain either a code security audit, penetration testing, or other audits +We are actively looking for sponsorship to obtain either a code security audit, penetration testing, or other audits related to improving the security of Authelia. If your company or you personally are willing to offer discounts, pro bono, or funding towards services like these please feel free to contact us on *any* of the methods above. -[security advisory]: https://github.com/authelia/authelia/security/advisories \ No newline at end of file +[security advisory]: https://github.com/authelia/authelia/security/advisories diff --git a/config.template.yml b/config.template.yml index e38dbda84..cb5e13b2f 100644 --- a/config.template.yml +++ b/config.template.yml @@ -15,7 +15,7 @@ theme: light ## The secret used to generate JWT tokens when validating user identity by email confirmation. JWT Secret can also be -## set using a secret: https://www.authelia.com/docs/configuration/secrets.html +## set using a secret: https://www.authelia.com/c/secrets jwt_secret: a_very_important_secret ## Default redirection URL @@ -52,7 +52,7 @@ server: # asset_path: /config/assets/ ## Buffers usually should be configured to be the same value. - ## Explanation at https://www.authelia.com/docs/configuration/server.html + ## Explanation at https://www.authelia.com/c/server#buffer-sizes ## Read buffer size adjusts the server's max incoming request size in bytes. ## Write buffer size does the same for outgoing responses. read_buffer_size: 4096 @@ -129,13 +129,13 @@ totp: ## The TOTP algorithm to use. ## It is CRITICAL you read the documentation before changing this option: - ## https://www.authelia.com/docs/configuration/one-time-password.html#algorithm + ## https://www.authelia.com/c/totp#algorithm algorithm: sha1 ## The number of digits a user has to input. Must either be 6 or 8. ## Changing this option only affects newly generated TOTP configurations. ## It is CRITICAL you read the documentation before changing this option: - ## https://www.authelia.com/docs/configuration/one-time-password.html#digits + ## https://www.authelia.com/c/totp#digits digits: 6 ## The period in seconds a one-time password is valid for. @@ -145,7 +145,8 @@ totp: ## The skew controls number of one-time passwords either side of the current one that are valid. ## Warning: before changing skew read the docs link below. skew: 1 - ## See: https://www.authelia.com/docs/configuration/one-time-password.html#input-validation to read the documentation. + ## See: https://www.authelia.com/c/totp#input-validation to read + ## the documentation. ## The size of the generated shared secrets. Default is 32 and is sufficient in most use cases, minimum is 20. secret_size: 32 @@ -181,7 +182,7 @@ duo_api: disable: false hostname: api-123456789.example.com integration_key: ABCDEF - ## Secret can also be set using a secret: https://www.authelia.com/docs/configuration/secrets.html + ## Secret can also be set using a secret: https://www.authelia.com/c/secrets secret_key: 1234567890abcdefghifjkl enable_self_enrollment: false @@ -230,8 +231,8 @@ authentication_backend: ## always belong to groups they belonged to at the time of login even if they have been removed from them in LDAP. ## To force update on every request you can set this to '0' or 'always', this will increase processor demand. ## See the below documentation for more information. - ## Duration Notation docs: https://www.authelia.com/docs/configuration/index.html#duration-notation-format - ## Refresh Interval docs: https://www.authelia.com/docs/configuration/authentication/ldap.html#refresh-interval + ## Duration Notation docs: https://www.authelia.com/c/common#duration-notation-format + ## Refresh Interval docs: https://www.authelia.com/c/1fa#refresh-interval refresh_interval: 5m ## @@ -249,7 +250,7 @@ authentication_backend: ## ## Depending on the option here certain other values in this section have a default value, notably all of the ## attribute mappings have a default value that this config overrides, you can read more about these default values - ## at https://www.authelia.com/docs/configuration/authentication/ldap.html#defaults + ## at https://www.authelia.com/c/ldap#defaults implementation: custom ## The url to the ldap server. Format: ://
[:]. @@ -294,7 +295,7 @@ authentication_backend: ## The users filter used in search queries to find the user profile based on input filled in login form. ## Various placeholders are available in the user filter which you can read about in the documentation which can - ## be found at: https://www.authelia.com/docs/configuration/authentication/ldap.html#users-filter-replacements + ## be found at: https://www.authelia.com/c/ldap#users-filter-replacements ## ## Recommended settings are as follows: ## - Microsoft Active Directory: (&({username_attribute}={input})(objectCategory=person)(objectClass=user)) @@ -312,7 +313,7 @@ authentication_backend: ## The groups filter used in search queries to find the groups based on relevant authenticated user. ## Various placeholders are available in the groups filter which you can read about in the documentation which can - ## be found at: https://www.authelia.com/docs/configuration/authentication/ldap.html#groups-filter-replacements + ## be found at: https://www.authelia.com/c/ldap#groups-filter-replacements ## ## If your groups use the `groupOfUniqueNames` structure use this instead: ## (&(uniqueMember={dn})(objectClass=groupOfUniqueNames)) @@ -334,7 +335,7 @@ authentication_backend: ## The username and password of the admin user. user: cn=admin,dc=example,dc=com - ## Password can also be set using a secret: https://www.authelia.com/docs/configuration/secrets.html + ## Password can also be set using a secret: https://www.authelia.com/c/secrets password: password ## @@ -345,9 +346,9 @@ authentication_backend: ## to be scaled to more than one instance. The options under 'password' have sane defaults, and as it has security ## implications it is highly recommended you leave the default values. Before considering changing these settings ## please read the docs page below: - ## https://www.authelia.com/docs/configuration/authentication/file.html#password-hash-algorithm-tuning + ## https://www.authelia.com/r/passwords#tuning ## - ## Important: Kubernetes (or HA) users must read https://www.authelia.com/docs/features/statelessness.html + ## Important: Kubernetes (or HA) users must read https://www.authelia.com/t/statelessness ## # file: # path: /config/users_database.yml @@ -524,15 +525,15 @@ session: domain: example.com ## Sets the Cookie SameSite value. Possible options are none, lax, or strict. - ## Please read https://www.authelia.com/docs/configuration/session/#same_site + ## Please read https://www.authelia.com/c/session#same_site same_site: lax ## The secret to encrypt the session data. This is only used with Redis / Redis Sentinel. - ## Secret can also be set using a secret: https://www.authelia.com/docs/configuration/secrets.html + ## Secret can also be set using a secret: https://www.authelia.com/c/secrets secret: insecure_session_secret ## The value for expiration, inactivity, and remember_me_duration are in seconds or the duration notation format. - ## See: https://www.authelia.com/docs/configuration/index.html#duration-notation-format + ## See: https://www.authelia.com/c/common#duration-notation-format ## All three of these values affect the cookie/session validity period. Longer periods are considered less secure ## because a stolen cookie will last longer giving attackers more time to spy or attack. @@ -551,7 +552,7 @@ session: ## ## Redis Provider ## - ## Important: Kubernetes (or HA) users must read https://www.authelia.com/docs/features/statelessness.html + ## Important: Kubernetes (or HA) users must read https://www.authelia.com/t/statelessness ## redis: host: 127.0.0.1 @@ -562,7 +563,7 @@ session: ## Username used for redis authentication. This is optional and a new feature in redis 6.0. # username: authelia - ## Password can also be set using a secret: https://www.authelia.com/docs/configuration/secrets.html + ## Password can also be set using a secret: https://www.authelia.com/c/secrets password: authelia ## This is the Redis DB Index https://redis.io/commands/select (sometimes referred to as database number, DB, etc). @@ -625,11 +626,11 @@ regulation: ## The time range during which the user can attempt login before being banned. The user is banned if the ## authentication failed 'max_retries' times in a 'find_time' seconds window. Find Time accepts duration notation. - ## See: https://www.authelia.com/docs/configuration/index.html#duration-notation-format + ## See: https://www.authelia.com/c/common#duration-notation-format find_time: 2m ## The length of time before a banned user can login again. Ban Time accepts duration notation. - ## See: https://www.authelia.com/docs/configuration/index.html#duration-notation-format + ## See: https://www.authelia.com/c/common#duration-notation-format ban_time: 5m ## @@ -647,7 +648,7 @@ storage: ## This stores the data in a SQLite3 Database. ## This is only recommended for lightweight non-stateful installations. ## - ## Important: Kubernetes (or HA) users must read https://www.authelia.com/docs/features/statelessness.html + ## Important: Kubernetes (or HA) users must read https://www.authelia.com/t/statelessness ## # local: # path: /config/db.sqlite3 @@ -660,7 +661,7 @@ storage: port: 3306 database: authelia username: authelia - ## Password can also be set using a secret: https://www.authelia.com/docs/configuration/secrets.html + ## Password can also be set using a secret: https://www.authelia.com/c/secrets password: mypassword timeout: 5s @@ -673,7 +674,7 @@ storage: # database: authelia # schema: public # username: authelia - # ## Password can also be set using a secret: https://www.authelia.com/docs/configuration/secrets.html + # ## Password can also be set using a secret: https://www.authelia.com/c/secrets # password: mypassword # timeout: 5s # ssl: @@ -694,7 +695,7 @@ notifier: ## ## File System (Notification Provider) ## - ## Important: Kubernetes (or HA) users must read https://www.authelia.com/docs/features/statelessness.html + ## Important: Kubernetes (or HA) users must read https://www.authelia.com/t/statelessness ## # filesystem: # filename: /config/notification.txt @@ -723,7 +724,7 @@ notifier: username: test ## The password used for SMTP authentication. - ## Can also be set using a secret: https://www.authelia.com/docs/configuration/secrets.html + ## Can also be set using a secret: https://www.authelia.com/c/secrets password: password ## The sender is used to is used for the MAIL FROM command and the FROM header. @@ -768,14 +769,14 @@ notifier: ## OpenID Connect (Identity Provider) ## ## It's recommended you read the documentation before configuration of this section: - ## https://www.authelia.com/docs/configuration/identity-providers/oidc.html + ## https://www.authelia.com/c/oidc # oidc: ## The hmac_secret is used to sign OAuth2 tokens (authorization code, access tokens and refresh tokens). - ## HMAC Secret can also be set using a secret: https://www.authelia.com/docs/configuration/secrets.html + ## HMAC Secret can also be set using a secret: https://www.authelia.com/c/secrets # hmac_secret: this_is_a_secret_abc123abc123abc ## The issuer_private_key is used to sign the JWT forged by OpenID Connect. - ## Issuer Private Key can also be set using a secret: https://docs.authelia.com/configuration/secrets.html + ## Issuer Private Key can also be set using a secret: https://www.authelia.com/c/secrets # issuer_private_key: | # --- KEY START # --- KEY END diff --git a/docs/.editorconfig b/docs/.editorconfig new file mode 100644 index 000000000..dad6b5822 --- /dev/null +++ b/docs/.editorconfig @@ -0,0 +1,11 @@ +# editorconfig.org + +root = true + +[*] +indent_style = space +indent_size = 2 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true \ No newline at end of file diff --git a/docs/.eslintignore b/docs/.eslintignore new file mode 100644 index 000000000..57d005799 --- /dev/null +++ b/docs/.eslintignore @@ -0,0 +1,4 @@ +assets/js/index.js +assets/js/katex.js +assets/js/vendor +node_modules \ No newline at end of file diff --git a/docs/.eslintrc.json b/docs/.eslintrc.json new file mode 100644 index 000000000..c926994dc --- /dev/null +++ b/docs/.eslintrc.json @@ -0,0 +1,31 @@ +{ + "env": { + "browser": true, + "commonjs": true, + "es6": true, + "node": true + }, + "extends": "eslint:recommended", + "globals": { + "Atomics": "readonly", + "SharedArrayBuffer": "readonly" + }, + "parserOptions": { + "ecmaVersion": 2018, + "sourceType": "module" + }, + "rules": { + "no-console": 0, + "quotes": ["error", "single"], + "comma-dangle": [ + "error", + { + "arrays": "always-multiline", + "objects": "always-multiline", + "imports": "always-multiline", + "exports": "always-multiline", + "functions": "ignore" + } + ] + } +} \ No newline at end of file diff --git a/docs/.gitignore b/docs/.gitignore index fcb2476de..6c3c7ae90 100644 --- a/docs/.gitignore +++ b/docs/.gitignore @@ -1,4 +1,6 @@ -_site -.sass-cache -.jekyll-metadata -.jekyll-cache +node_modules +public +resources +.netlify +.hugo_build.lock +!content/*/reference/cli/authelia diff --git a/docs/.markdownlint-cli2.jsonc b/docs/.markdownlint-cli2.jsonc new file mode 100644 index 000000000..f3168449f --- /dev/null +++ b/docs/.markdownlint-cli2.jsonc @@ -0,0 +1,20 @@ +{ + "config": { + "default": true, + "MD013": false, + "MD024": false, + "MD026": false, + "MD033": false, + "MD034": false, + "emphasis-style": { + "style": "asterisk" + }, + "strong-style": { + "style": "underscore" + }, + "ul-style": { + "style": "asterisk" + } + }, + "ignores": ["node_modules", "CHANGELOG.md", "README.md", "content/*/reference/cli"] +} diff --git a/docs/.stylelintignore b/docs/.stylelintignore new file mode 100644 index 000000000..3972095a3 --- /dev/null +++ b/docs/.stylelintignore @@ -0,0 +1,3 @@ +assets/scss/components/_syntax.scss +assets/scss/vendor +node_modules \ No newline at end of file diff --git a/docs/.stylelintrc.json b/docs/.stylelintrc.json new file mode 100644 index 000000000..191d09381 --- /dev/null +++ b/docs/.stylelintrc.json @@ -0,0 +1,48 @@ +{ + "extends": "stylelint-config-standard-scss", + "rules": { + "no-empty-source": null, + "string-quotes": "double", + "scss/comment-no-empty": null, + "max-line-length": null, + "scss/at-extend-no-missing-placeholder": null, + "scss/dollar-variable-colon-space-after": null, + "scss/dollar-variable-empty-line-before": null, + "color-function-notation": null, + "alpha-value-notation": null, + "selector-id-pattern": null, + "selector-class-pattern": null, + "scss/no-global-function-names": null, + "number-max-precision": null, + "hue-degree-notation": null, + "value-no-vendor-prefix": null, + "property-no-vendor-prefix": null, + "at-rule-no-unknown": [ + true, + { + "ignoreAtRules": [ + "extend", + "at-root", + "debug", + "warn", + "error", + "if", + "else", + "for", + "each", + "while", + "mixin", + "include", + "content", + "return", + "function", + "tailwind", + "apply", + "responsive", + "variants", + "screen" + ] + } + ] + } +} \ No newline at end of file diff --git a/docs/Gemfile b/docs/Gemfile deleted file mode 100644 index d63015943..000000000 --- a/docs/Gemfile +++ /dev/null @@ -1,30 +0,0 @@ -source "https://rubygems.org" - -# Hello! This is where you manage which Jekyll version is used to run. -# When you want to use a different version, change it below, save the -# file and run `bundle install`. Run Jekyll with `bundle exec`, like so: -# -# bundle exec jekyll serve -# -# This will help ensure the proper Jekyll version is running. -# Happy Jekylling! -gem "jekyll", "~> 3.9.0" - -# This is the default theme for new Jekyll sites. You may change this to anything you like. -#gem "minima", "~> 2.0" -gem "just-the-docs" - -# If you want to use GitHub Pages, remove the "gem "jekyll"" above and -# uncomment the line below. To upgrade, run `bundle update github-pages`. -gem "github-pages", group: :jekyll_plugins - -# If you have any plugins, put them here! -group :jekyll_plugins do - # gem "jekyll-feed", "~> 0.6" -end - -# Windows does not include zoneinfo files, so bundle the tzinfo-data gem -gem "tzinfo-data", platforms: [:mingw, :mswin, :x64_mingw, :jruby] - -# Performance-booster for watching directories on Windows -gem "wdm", "~> 0.1.0" if Gem.win_platform? diff --git a/docs/Gemfile.lock b/docs/Gemfile.lock deleted file mode 100644 index 5f3ff5d60..000000000 --- a/docs/Gemfile.lock +++ /dev/null @@ -1,273 +0,0 @@ -GEM - remote: https://rubygems.org/ - specs: - activesupport (6.0.3.6) - concurrent-ruby (~> 1.0, >= 1.0.2) - i18n (>= 0.7, < 2) - minitest (~> 5.1) - tzinfo (~> 1.1) - zeitwerk (~> 2.2, >= 2.2.2) - addressable (2.8.0) - public_suffix (>= 2.0.2, < 5.0) - coffee-script (2.4.1) - coffee-script-source - execjs - coffee-script-source (1.11.1) - colorator (1.1.0) - commonmarker (0.17.13) - ruby-enum (~> 0.5) - concurrent-ruby (1.1.8) - dnsruby (1.61.5) - simpleidn (~> 0.1) - em-websocket (0.5.2) - eventmachine (>= 0.12.9) - http_parser.rb (~> 0.6.0) - ethon (0.12.0) - ffi (>= 1.3.0) - eventmachine (1.2.7) - execjs (2.7.0) - faraday (1.3.0) - faraday-net_http (~> 1.0) - multipart-post (>= 1.2, < 3) - ruby2_keywords - faraday-net_http (1.0.1) - ffi (1.15.0) - forwardable-extended (2.6.0) - gemoji (3.0.1) - github-pages (214) - github-pages-health-check (= 1.17.0) - jekyll (= 3.9.0) - jekyll-avatar (= 0.7.0) - jekyll-coffeescript (= 1.1.1) - jekyll-commonmark-ghpages (= 0.1.6) - jekyll-default-layout (= 0.1.4) - jekyll-feed (= 0.15.1) - jekyll-gist (= 1.5.0) - jekyll-github-metadata (= 2.13.0) - jekyll-mentions (= 1.6.0) - jekyll-optional-front-matter (= 0.3.2) - jekyll-paginate (= 1.1.0) - jekyll-readme-index (= 0.3.0) - jekyll-redirect-from (= 0.16.0) - jekyll-relative-links (= 0.6.1) - jekyll-remote-theme (= 0.4.3) - jekyll-sass-converter (= 1.5.2) - jekyll-seo-tag (= 2.7.1) - jekyll-sitemap (= 1.4.0) - jekyll-swiss (= 1.0.0) - jekyll-theme-architect (= 0.1.1) - jekyll-theme-cayman (= 0.1.1) - jekyll-theme-dinky (= 0.1.1) - jekyll-theme-hacker (= 0.1.2) - jekyll-theme-leap-day (= 0.1.1) - jekyll-theme-merlot (= 0.1.1) - jekyll-theme-midnight (= 0.1.1) - jekyll-theme-minimal (= 0.1.1) - jekyll-theme-modernist (= 0.1.1) - jekyll-theme-primer (= 0.5.4) - jekyll-theme-slate (= 0.1.1) - jekyll-theme-tactile (= 0.1.1) - jekyll-theme-time-machine (= 0.1.1) - jekyll-titles-from-headings (= 0.5.3) - jemoji (= 0.12.0) - kramdown (= 2.3.1) - kramdown-parser-gfm (= 1.1.0) - liquid (= 4.0.3) - mercenary (~> 0.3) - minima (= 2.5.1) - nokogiri (>= 1.10.4, < 2.0) - rouge (= 3.26.0) - terminal-table (~> 1.4) - github-pages-health-check (1.17.0) - addressable (~> 2.3) - dnsruby (~> 1.60) - octokit (~> 4.0) - public_suffix (>= 2.0.2, < 5.0) - typhoeus (~> 1.3) - html-pipeline (2.14.0) - activesupport (>= 2) - nokogiri (>= 1.4) - http_parser.rb (0.6.0) - i18n (0.9.5) - concurrent-ruby (~> 1.0) - jekyll (3.9.0) - addressable (~> 2.4) - colorator (~> 1.0) - em-websocket (~> 0.5) - i18n (~> 0.7) - jekyll-sass-converter (~> 1.0) - jekyll-watch (~> 2.0) - kramdown (>= 1.17, < 3) - liquid (~> 4.0) - mercenary (~> 0.3.3) - pathutil (~> 0.9) - rouge (>= 1.7, < 4) - safe_yaml (~> 1.0) - jekyll-avatar (0.7.0) - jekyll (>= 3.0, < 5.0) - jekyll-coffeescript (1.1.1) - coffee-script (~> 2.2) - coffee-script-source (~> 1.11.1) - jekyll-commonmark (1.3.1) - commonmarker (~> 0.14) - jekyll (>= 3.7, < 5.0) - jekyll-commonmark-ghpages (0.1.6) - commonmarker (~> 0.17.6) - jekyll-commonmark (~> 1.2) - rouge (>= 2.0, < 4.0) - jekyll-default-layout (0.1.4) - jekyll (~> 3.0) - jekyll-feed (0.15.1) - jekyll (>= 3.7, < 5.0) - jekyll-gist (1.5.0) - octokit (~> 4.2) - jekyll-github-metadata (2.13.0) - jekyll (>= 3.4, < 5.0) - octokit (~> 4.0, != 4.4.0) - jekyll-mentions (1.6.0) - html-pipeline (~> 2.3) - jekyll (>= 3.7, < 5.0) - jekyll-optional-front-matter (0.3.2) - jekyll (>= 3.0, < 5.0) - jekyll-paginate (1.1.0) - jekyll-readme-index (0.3.0) - jekyll (>= 3.0, < 5.0) - jekyll-redirect-from (0.16.0) - jekyll (>= 3.3, < 5.0) - jekyll-relative-links (0.6.1) - jekyll (>= 3.3, < 5.0) - jekyll-remote-theme (0.4.3) - addressable (~> 2.0) - jekyll (>= 3.5, < 5.0) - jekyll-sass-converter (>= 1.0, <= 3.0.0, != 2.0.0) - rubyzip (>= 1.3.0, < 3.0) - jekyll-sass-converter (1.5.2) - sass (~> 3.4) - jekyll-seo-tag (2.7.1) - jekyll (>= 3.8, < 5.0) - jekyll-sitemap (1.4.0) - jekyll (>= 3.7, < 5.0) - jekyll-swiss (1.0.0) - jekyll-theme-architect (0.1.1) - jekyll (~> 3.5) - jekyll-seo-tag (~> 2.0) - jekyll-theme-cayman (0.1.1) - jekyll (~> 3.5) - jekyll-seo-tag (~> 2.0) - jekyll-theme-dinky (0.1.1) - jekyll (~> 3.5) - jekyll-seo-tag (~> 2.0) - jekyll-theme-hacker (0.1.2) - jekyll (> 3.5, < 5.0) - jekyll-seo-tag (~> 2.0) - jekyll-theme-leap-day (0.1.1) - jekyll (~> 3.5) - jekyll-seo-tag (~> 2.0) - jekyll-theme-merlot (0.1.1) - jekyll (~> 3.5) - jekyll-seo-tag (~> 2.0) - jekyll-theme-midnight (0.1.1) - jekyll (~> 3.5) - jekyll-seo-tag (~> 2.0) - jekyll-theme-minimal (0.1.1) - jekyll (~> 3.5) - jekyll-seo-tag (~> 2.0) - jekyll-theme-modernist (0.1.1) - jekyll (~> 3.5) - jekyll-seo-tag (~> 2.0) - jekyll-theme-primer (0.5.4) - jekyll (> 3.5, < 5.0) - jekyll-github-metadata (~> 2.9) - jekyll-seo-tag (~> 2.0) - jekyll-theme-slate (0.1.1) - jekyll (~> 3.5) - jekyll-seo-tag (~> 2.0) - jekyll-theme-tactile (0.1.1) - jekyll (~> 3.5) - jekyll-seo-tag (~> 2.0) - jekyll-theme-time-machine (0.1.1) - jekyll (~> 3.5) - jekyll-seo-tag (~> 2.0) - jekyll-titles-from-headings (0.5.3) - jekyll (>= 3.3, < 5.0) - jekyll-watch (2.2.1) - listen (~> 3.0) - jemoji (0.12.0) - gemoji (~> 3.0) - html-pipeline (~> 2.2) - jekyll (>= 3.0, < 5.0) - just-the-docs (0.3.3) - jekyll (>= 3.8.5) - jekyll-seo-tag (~> 2.0) - rake (>= 12.3.1, < 13.1.0) - kramdown (2.3.1) - rexml - kramdown-parser-gfm (1.1.0) - kramdown (~> 2.0) - liquid (4.0.3) - listen (3.5.1) - rb-fsevent (~> 0.10, >= 0.10.3) - rb-inotify (~> 0.9, >= 0.9.10) - mercenary (0.3.6) - mini_portile2 (2.8.0) - minima (2.5.1) - jekyll (>= 3.5, < 5.0) - jekyll-feed (~> 0.9) - jekyll-seo-tag (~> 2.1) - minitest (5.14.4) - multipart-post (2.1.1) - nokogiri (1.13.6) - mini_portile2 (~> 2.8.0) - racc (~> 1.4) - octokit (4.20.0) - faraday (>= 0.9) - sawyer (~> 0.8.0, >= 0.5.3) - pathutil (0.16.2) - forwardable-extended (~> 2.6) - public_suffix (4.0.6) - racc (1.6.0) - rake (13.0.3) - rb-fsevent (0.10.4) - rb-inotify (0.10.1) - ffi (~> 1.0) - rexml (3.2.5) - rouge (3.26.0) - ruby-enum (0.9.0) - i18n - ruby2_keywords (0.0.4) - rubyzip (2.3.0) - safe_yaml (1.0.5) - sass (3.7.4) - sass-listen (~> 4.0.0) - sass-listen (4.0.0) - rb-fsevent (~> 0.9, >= 0.9.4) - rb-inotify (~> 0.9, >= 0.9.7) - sawyer (0.8.2) - addressable (>= 2.3.5) - faraday (> 0.8, < 2.0) - simpleidn (0.2.1) - unf (~> 0.1.4) - terminal-table (1.8.0) - unicode-display_width (~> 1.1, >= 1.1.1) - thread_safe (0.3.6) - typhoeus (1.4.0) - ethon (>= 0.9.0) - tzinfo (1.2.9) - thread_safe (~> 0.1) - unf (0.1.4) - unf_ext - unf_ext (0.0.7.7) - unicode-display_width (1.7.0) - zeitwerk (2.4.2) - -PLATFORMS - ruby - -DEPENDENCIES - github-pages - jekyll (~> 3.9.0) - just-the-docs - tzinfo-data - -BUNDLED WITH - 2.2.3 diff --git a/docs/LICENSE b/docs/LICENSE new file mode 100644 index 000000000..a9431aad1 --- /dev/null +++ b/docs/LICENSE @@ -0,0 +1,22 @@ +MIT License + +Copyright (c) 2018-present, Gridsome +Copyright (c) 2020-present, Henk Verlinde + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 000000000..c16c540b2 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,9 @@ +The **Authelia** website / documentation source. + +Please: + +- Only edit the `/content` folder via the main Authelia [monorepo](https://github.com/authelia/authelia/tree/master/docs) +- Edit everything else via the Authelia [website repo](https://github.com/authelia/website) + +See the [Documentation Contributing Guide](https://www.authelia.com/contributing/prologue/documentation/) for more +information. diff --git a/docs/_config.yml b/docs/_config.yml deleted file mode 100644 index 54b87556d..000000000 --- a/docs/_config.yml +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: Authelia -email: team@authelia.com -description: Authelia is an open source multi-factor single sign-on portal for web applications -# We need this base URL to serve the docs under https://www.authelia.com/docs/ -baseurl: "/docs/" -# url: "https://www.authelia.com" -repository: https://github.com/authelia/authelia -logo: ./images/authelia-title.png -footer_content: > - Copyright © 2022 Authelia. Distributed by an - Apache 2.0 license. -markdown: kramdown -theme: just-the-docs -keep_files: - - .git - - CNAME -ga_tracking: UA-124926127-1 -... diff --git a/docs/_includes/head_custom.html b/docs/_includes/head_custom.html deleted file mode 100644 index 4dad5dc58..000000000 --- a/docs/_includes/head_custom.html +++ /dev/null @@ -1,4 +0,0 @@ - - diff --git a/docs/_layouts/default.html b/docs/_layouts/default.html deleted file mode 100644 index fa6300c6a..000000000 --- a/docs/_layouts/default.html +++ /dev/null @@ -1,262 +0,0 @@ ---- -layout: table_wrappers ---- - - - - -{% include head.html %} - -Fork me on GitHub - - - Link - - - - - - Search - - - - - - Menu - - - - - - Expand - - - - - - Document - - - - - - Survey contribution - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- {% if site.search_enabled != false %} - - {% endif %} - {% if site.aux_links %} - - {% endif %} -
-
- {% unless page.url == "/" %} - {% if page.parent %} - - {% endif %} - {% endunless %} -
- - Help the team improve Authelia by taking this 10-second survey. -
-
- {% if site.heading_anchors != false %} - {% include vendor/anchor_headings.html html=content beforeHeading="true" anchorBody="" anchorClass="anchor-heading" anchorAttrs="aria-labelledby=\"%html_id%\"" %} - {% else %} - {{ content }} - {% endif %} - - {% if page.has_children == true and page.has_toc != false %} -
-

Table of contents

-
    - {%- assign children_list = pages_list | where: "parent", page.title | where: "grand_parent", page.parent -%} - {% for child in children_list %} -
  • - {{ child.title }}{% if child.summary %} - {{ child.summary }}{% endif %} -
  • - {% endfor %} -
- {% endif %} - - {% if site.footer_content != nil or site.last_edit_timestamp or site.gh_edit_link %} -
-
- {% if site.back_to_top %} -

{{ site.back_to_top_text }}

- {% endif %} - {% if site.footer_content != nil %} -

{{ site.footer_content }}

- {% endif %} - - {% if site.last_edit_timestamp or site.gh_edit_link %} -
- {% if site.last_edit_timestamp and site.last_edit_time_format and page.last_modified_date %} -

- Page last modified: {{ page.last_modified_date | date: site.last_edit_time_format }}. -

- {% endif %} - {% if - site.gh_edit_link and - site.gh_edit_link_text and - site.gh_edit_repository and - site.gh_edit_branch and - site.gh_edit_view_mode - %} -

- {{ site.gh_edit_link_text }} -

- {% endif %} -
- {% endif %} -
- {% endif %} - -
-
- - {% if site.search_enabled != false %} - {% if site.search.button %} - - - - {% endif %} - -
- {% endif %} -
- - \ No newline at end of file diff --git a/docs/_sass/custom/custom.scss b/docs/_sass/custom/custom.scss deleted file mode 100644 index 2edf9f74e..000000000 --- a/docs/_sass/custom/custom.scss +++ /dev/null @@ -1,19 +0,0 @@ -.label.label-config { - text-transform: none; -} -.tbl-header { - font-weight: bold; - text-align: center; -} -.tbl-beta-stage { - border-bottom-width: 3px !important; -} -.material-icons.green { - color: #56D364; -} -.material-icons.red { - color: #F85149; -} -.material-icons.orange { - color: #E3B341; -} \ No newline at end of file diff --git a/docs/_sass/overrides.scss b/docs/_sass/overrides.scss deleted file mode 100644 index cba6cefdc..000000000 --- a/docs/_sass/overrides.scss +++ /dev/null @@ -1,10 +0,0 @@ - -img { - border: 1px solid #e6e6e6; - border-radius: 5px; - padding: 10px; -} - -.no-border { - border: 0px; -} \ No newline at end of file diff --git a/docs/about-us.md b/docs/about-us.md deleted file mode 100644 index 1b70839a5..000000000 --- a/docs/about-us.md +++ /dev/null @@ -1,69 +0,0 @@ ---- -layout: default -title: About Us -nav_order: 10 ---- - -## Core Team - - - - - -
- - -
- - Clément Michaud - -
-
- - -
- - Amir Zarrinkafsh - -
-
- - -
- - James Elliott - -
-
- - -## Contact Options - -Several contact options exist for our community, the primary one being [Matrix](#matrix). These are in addition to -[GitHub issues](https://github.com/authelia/authelia/issues) for creating a [new issue](https://github.com/authelia/authelia/issues/new/choose). - -### Matrix - -Community members are invited to join the [Matrix Space](https://matrix.to/#/#community:authelia.com) which includes both -the [Support Room](https://matrix.to/#/#support:authelia.com) and the [Contributing Room](https://matrix.to/#/#contributing:authelia.com). - -- The core team members are identified as administrators in the Space and individual Rooms. -- All channels are linked to [Discord](#discord). - -### Discord - -Community members are invited to join the [Discord Server](https://discord.authelia.com). - -- The core team members are identified by the **CORE TEAM** role in Discord. -- The [#support] and [#contributing] channels are linked to [Matrix](#matrix). - -### Email - -You can contact the core team by email via [team@authelia.com](mailto:team@authelia.com). Please note the -[security@authelia.com](mailto:security@authelia.com) is also available but is strictly reserved for [security] related -matters. - - -[security]: https://github.com/authelia/authelia/security/policy -[#support]: https://discord.com/channels/707844280412012608/707844280412012612 -[#contributing]: https://discord.com/channels/707844280412012608/804943261265297408 \ No newline at end of file diff --git a/docs/archetypes/blog.md b/docs/archetypes/blog.md new file mode 100644 index 000000000..b4ad21a4c --- /dev/null +++ b/docs/archetypes/blog.md @@ -0,0 +1,11 @@ +--- +title: "{{ replace .Name "-" " " | title }}" +description: "" +lead: "" +date: {{ .Date }} +lastmod: {{ .Date }} +draft: true +weight: 50 +images: ["{{ .Name | urlize }}.jpg"] +contributors: [] +--- diff --git a/docs/archetypes/configuration.md b/docs/archetypes/configuration.md new file mode 100644 index 000000000..7118ea64f --- /dev/null +++ b/docs/archetypes/configuration.md @@ -0,0 +1,14 @@ +--- +title: "{{ replace .Name "-" " " | title }}" +description: "" +lead: "" +date: {{ .Date }} +lastmod: {{ .Date }} +draft: true +images: [] +menu: + configuration: + parent: "" +weight: 999 +toc: true +--- diff --git a/docs/archetypes/default.md b/docs/archetypes/default.md new file mode 100644 index 000000000..d8210df1b --- /dev/null +++ b/docs/archetypes/default.md @@ -0,0 +1,8 @@ +--- +title: "{{ replace .Name "-" " " | title }}" +description: "" +date: {{ .Date }} +lastmod: {{ .Date }} +draft: true +images: [] +--- diff --git a/docs/archetypes/docs.md b/docs/archetypes/docs.md new file mode 100644 index 000000000..436bd0863 --- /dev/null +++ b/docs/archetypes/docs.md @@ -0,0 +1,14 @@ +--- +title: "{{ replace .Name "-" " " | title }}" +description: "" +lead: "" +date: {{ .Date }} +lastmod: {{ .Date }} +draft: true +images: [] +menu: + docs: + parent: "" +weight: 999 +toc: true +--- diff --git a/docs/assets/fonts/.gitkeep b/docs/assets/fonts/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/docs/assets/images/.gitkeep b/docs/assets/images/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/docs/assets/js/alert-init.js b/docs/assets/js/alert-init.js new file mode 100644 index 000000000..af3ac3254 --- /dev/null +++ b/docs/assets/js/alert-init.js @@ -0,0 +1,5 @@ +Object.keys(localStorage).forEach(function(key) { + if (/^global-alert-/.test(key)) { + document.documentElement.setAttribute('data-global-alert', 'closed'); + } +}); \ No newline at end of file diff --git a/docs/assets/js/alert.js b/docs/assets/js/alert.js new file mode 100644 index 000000000..1956103d8 --- /dev/null +++ b/docs/assets/js/alert.js @@ -0,0 +1,20 @@ +var announcement = document.getElementById('announcement'); + +if (announcement !== null) { + + var id = announcement.dataset.id; + + Object.keys(localStorage).forEach(function(key) { + if (/^global-alert-/.test(key)) { + if (key !== id ) { + localStorage.removeItem(key); + document.documentElement.removeAttribute('data-global-alert'); + } + } + }); + + announcement.addEventListener('closed.bs.alert', () => { + localStorage.setItem(id, 'closed'); + }); + +} \ No newline at end of file diff --git a/docs/assets/js/app.js b/docs/assets/js/app.js new file mode 100644 index 000000000..e69de29bb diff --git a/docs/assets/js/bootstrap.js b/docs/assets/js/bootstrap.js new file mode 100644 index 000000000..17f9621f9 --- /dev/null +++ b/docs/assets/js/bootstrap.js @@ -0,0 +1 @@ +import 'bootstrap/dist/js/bootstrap.bundle.min.js' diff --git a/docs/assets/js/clipboard.js b/docs/assets/js/clipboard.js new file mode 100644 index 000000000..55eec7b36 --- /dev/null +++ b/docs/assets/js/clipboard.js @@ -0,0 +1,37 @@ +import Clipboard from 'clipboard'; + +var pre = document.getElementsByTagName('pre'); + +for (var i = 0; i < pre.length; ++ i) +{ + var element = pre[i]; + var mermaid = element.getElementsByClassName('language-mermaid')[0]; + + if (mermaid == null) { + element.insertAdjacentHTML('afterbegin', ''); + } +} + +var clipboard = new Clipboard('.btn-copy', { + + target: function(trigger) { + return trigger.nextElementSibling; + }, + +}); + +clipboard.on('success', function(e) { + + /* + console.info('Action:', e.action); + console.info('Text:', e.text); + console.info('Trigger:', e.trigger); + */ + + e.clearSelection(); +}); + +clipboard.on('error', function(e) { + console.error('Action:', e.action); + console.error('Trigger:', e.trigger); +}); diff --git a/docs/assets/js/darkmode-init.js b/docs/assets/js/darkmode-init.js new file mode 100644 index 000000000..0f3508deb --- /dev/null +++ b/docs/assets/js/darkmode-init.js @@ -0,0 +1,21 @@ +const globalDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches; +const localMode = localStorage.getItem('theme'); + +if (globalDark && (localMode === null)) { + + localStorage.setItem('theme', 'dark'); + document.documentElement.setAttribute('data-dark-mode', ''); + +} + +if (globalDark && (localMode === 'dark')) { + + document.documentElement.setAttribute('data-dark-mode', ''); + +} + +if (localMode === 'dark') { + + document.documentElement.setAttribute('data-dark-mode', ''); + +} diff --git a/docs/assets/js/darkmode.js b/docs/assets/js/darkmode.js new file mode 100644 index 000000000..e81db47d7 --- /dev/null +++ b/docs/assets/js/darkmode.js @@ -0,0 +1,38 @@ +const mode = document.getElementById('mode'); + +if (mode !== null) { + + window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', event => { + + if (event.matches) { + + localStorage.setItem('theme', 'dark'); + document.documentElement.setAttribute('data-dark-mode', ''); + + } else { + + localStorage.setItem('theme', 'light'); + document.documentElement.removeAttribute('data-dark-mode'); + + } + + }) + + mode.addEventListener('click', () => { + + document.documentElement.toggleAttribute('data-dark-mode'); + localStorage.setItem('theme', document.documentElement.hasAttribute('data-dark-mode') ? 'dark' : 'light'); + + }); + + if (localStorage.getItem('theme') === 'dark') { + + document.documentElement.setAttribute('data-dark-mode', ''); + + } else { + + document.documentElement.removeAttribute('data-dark-mode'); + + } + +} diff --git a/docs/assets/js/highlight.js b/docs/assets/js/highlight.js new file mode 100644 index 000000000..381952488 --- /dev/null +++ b/docs/assets/js/highlight.js @@ -0,0 +1,44 @@ +import hljs from 'highlight.js/lib/core'; + +import go from 'highlight.js/lib/languages/go'; +import json from 'highlight.js/lib/languages/json'; +import bash from 'highlight.js/lib/languages/bash'; +import xml from 'highlight.js/lib/languages/xml'; +import yaml from 'highlight.js/lib/languages/yaml'; +import dockerfile from 'highlight.js/lib/languages/dockerfile'; +import nginx from 'highlight.js/lib/languages/nginx'; +import ruby from 'highlight.js/lib/languages/ruby'; +import plaintext from 'highlight.js/lib/languages/plaintext'; +import php from 'highlight.js/lib/languages/php'; +import python from 'highlight.js/lib/languages/python'; +import ldif from 'highlight.js/lib/languages/ldif'; +import ini from 'highlight.js/lib/languages/ini'; + +hljs.registerLanguage('go', go); +hljs.registerLanguage('json', json); +hljs.registerLanguage('bash', bash); +hljs.registerLanguage('console', bash); +hljs.registerLanguage('sh', bash); +hljs.registerLanguage('shell', bash); +hljs.registerLanguage('html', xml); +hljs.registerLanguage('yaml', yaml); +hljs.registerLanguage('yml', yaml); +hljs.registerLanguage('dockerfile', dockerfile); +hljs.registerLanguage('nginx', nginx); +hljs.registerLanguage('ruby', ruby); +hljs.registerLanguage('rb', ruby); +hljs.registerLanguage('plaintext', plaintext); +hljs.registerLanguage('php', php); +hljs.registerLanguage('text', plaintext); +hljs.registerLanguage('txt', plaintext); +hljs.registerLanguage('python', python); +hljs.registerLanguage('py', python); +hljs.registerLanguage('ldif', ldif); +hljs.registerLanguage('ini', ini); +hljs.registerLanguage('cnf', ini); + +document.addEventListener('DOMContentLoaded', () => { + document.querySelectorAll('pre code:not(.language-mermaid)').forEach((block) => { + hljs.highlightElement(block); + }); +}); diff --git a/docs/assets/js/index.js b/docs/assets/js/index.js new file mode 100644 index 000000000..672d6c7a6 --- /dev/null +++ b/docs/assets/js/index.js @@ -0,0 +1,169 @@ +var suggestions = document.getElementById('suggestions'); +var search = document.getElementById('search'); + +if (search !== null) { + document.addEventListener('keydown', inputFocus); +} + +function inputFocus(e) { + if (e.ctrlKey && e.key === '/' ) { + e.preventDefault(); + search.focus(); + } + if (e.key === 'Escape' ) { + search.blur(); + suggestions.classList.add('d-none'); + } +} + +document.addEventListener('click', function(event) { + + var isClickInsideElement = suggestions.contains(event.target); + + if (!isClickInsideElement) { + suggestions.classList.add('d-none'); + } + +}); + +/* +Source: + - https://dev.to/shubhamprakash/trap-focus-using-javascript-6a3 +*/ + +document.addEventListener('keydown',suggestionFocus); + +function suggestionFocus(e) { + const suggestionsHidden = suggestions.classList.contains('d-none'); + if (suggestionsHidden) return; + + const focusableSuggestions= [...suggestions.querySelectorAll('a')]; + if (focusableSuggestions.length === 0) return; + + const index = focusableSuggestions.indexOf(document.activeElement); + + if (e.key === "ArrowUp") { + e.preventDefault(); + const nextIndex = index > 0 ? index - 1 : 0; + focusableSuggestions[nextIndex].focus(); + } + else if (e.key === "ArrowDown") { + e.preventDefault(); + const nextIndex= index + 1 < focusableSuggestions.length ? index + 1 : index; + focusableSuggestions[nextIndex].focus(); + } + +} + +/* +Source: + - https://github.com/nextapps-de/flexsearch#index-documents-field-search + - https://raw.githack.com/nextapps-de/flexsearch/master/demo/autocomplete.html +*/ + +(function(){ + + var index = new FlexSearch.Document({ + tokenize: "forward", + cache: 100, + document: { + id: 'id', + store: [ + "href", "title", "description" + ], + index: ["title", "description", "content"] + } + }); + + + // Not yet supported: https://github.com/nextapps-de/flexsearch#complex-documents + + /* + var docs = [ + {{ range $index, $page := (where .Site.Pages "Section" "docs") -}} + { + id: {{ $index }}, + href: "{{ .Permalink }}", + title: {{ .Title | jsonify }}, + description: {{ .Params.description | jsonify }}, + content: {{ .Content | jsonify }} + }, + {{ end -}} + ]; + */ + + // https://discourse.gohugo.io/t/range-length-or-last-element/3803/2 + + {{ $list := (where .Site.RegularPages "Type" "in" (union .Site.Params.Sections.Search .Site.Params.Sections.Searchable)) -}} + {{ $len := (len $list) -}} + + index.add( + {{ range $index, $element := $list -}} + { + id: {{ $index }}, + href: "{{ .RelPermalink }}", + title: {{ .Title | jsonify }}, + {{ with .Description -}} + description: {{ . | jsonify }}, + {{ else -}} + description: {{ .Summary | plainify | jsonify }}, + {{ end -}} + content: {{ .Plain | jsonify }} + }) + {{ if ne (add $index 1) $len -}} + .add( + {{ end -}} + {{ end -}} + ; + + search.addEventListener('input', show_results, true); + + function show_results(){ + const maxResult = 5; + var searchQuery = this.value; + var results = index.search(searchQuery, {limit: maxResult, enrich: true}); + + // flatten results since index.search() returns results for each indexed field + const flatResults = new Map(); // keyed by href to dedupe results + for (const result of results.flatMap(r => r.result)) { + if (flatResults.has(result.doc.href)) continue; + flatResults.set(result.doc.href, result.doc); + } + + suggestions.innerHTML = ""; + suggestions.classList.remove('d-none'); + + // inform user that no results were found + if (flatResults.size === 0 && searchQuery) { + const noResultsMessage = document.createElement('div') + noResultsMessage.innerHTML = `No results for "${searchQuery}"` + noResultsMessage.classList.add("suggestion__no-results"); + suggestions.appendChild(noResultsMessage); + return; + } + + // construct a list of suggestions + for(const [href, doc] of flatResults) { + const entry = document.createElement('div'); + suggestions.appendChild(entry); + + const a = document.createElement('a'); + a.href = href; + entry.appendChild(a); + + const title = document.createElement('span'); + title.textContent = doc.title; + title.classList.add("suggestion__title"); + a.appendChild(title); + + const description = document.createElement('span'); + description.textContent = doc.description; + description.classList.add("suggestion__description"); + a.appendChild(description); + + suggestions.appendChild(entry); + + if(suggestions.childElementCount == maxResult) break; + } + } +}()); diff --git a/docs/assets/js/instant.page.js b/docs/assets/js/instant.page.js new file mode 100644 index 000000000..b394bcc4c --- /dev/null +++ b/docs/assets/js/instant.page.js @@ -0,0 +1 @@ +import 'instant.page'; diff --git a/docs/assets/js/katex.js b/docs/assets/js/katex.js new file mode 100644 index 000000000..e0543eafe --- /dev/null +++ b/docs/assets/js/katex.js @@ -0,0 +1,10 @@ +document.addEventListener('DOMContentLoaded', function() { + renderMathInElement(document.body, { + delimiters: [ + {left: '$$', right: '$$', display: true}, + {left: '$', right: '$', display: false}, + {left: '\\(', right: '\\)', display: false}, + {left: '\\[', right: '\\]', display: true}, + ], + }); +}); diff --git a/docs/assets/js/lazysizes.js b/docs/assets/js/lazysizes.js new file mode 100644 index 000000000..c12ed585d --- /dev/null +++ b/docs/assets/js/lazysizes.js @@ -0,0 +1 @@ +import 'lazysizes'; diff --git a/docs/assets/js/mermaid.js b/docs/assets/js/mermaid.js new file mode 100644 index 000000000..b214d5f7f --- /dev/null +++ b/docs/assets/js/mermaid.js @@ -0,0 +1,11 @@ +import mermaid from 'mermaid'; + +var config = { + theme: 'default', + fontFamily: '"Jost", -apple-system, blinkmacsystemfont, "Segoe UI", roboto, "Helvetica Neue", arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";', +}; + +document.addEventListener('DOMContentLoaded', () => { + mermaid.initialize(config); + mermaid.init(undefined, '.language-mermaid'); +}); diff --git a/docs/assets/js/scroll-lock.js b/docs/assets/js/scroll-lock.js new file mode 100644 index 000000000..069b8c2e3 --- /dev/null +++ b/docs/assets/js/scroll-lock.js @@ -0,0 +1,14 @@ +// Adds scroll position lock for default docs sidebar + +if (document.querySelector('#sidebar-default') !== null) { + let sidebar = document.getElementById('sidebar-default'); + + let pos = sessionStorage.getItem('sidebar-scroll'); + if (pos !== null) { + sidebar.scrollTop = parseInt(pos, 10); + } + + window.addEventListener('beforeunload', () => { + sessionStorage.setItem('sidebar-scroll', sidebar.scrollTop); + }); +} diff --git a/docs/assets/js/vendor/.gitkeep b/docs/assets/js/vendor/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/docs/assets/scss/app.scss b/docs/assets/scss/app.scss new file mode 100644 index 000000000..6d489fb2f --- /dev/null +++ b/docs/assets/scss/app.scss @@ -0,0 +1,37 @@ +/** Import Bootstrap functions */ +@import "bootstrap/scss/functions"; + +/** Import theme variables */ +@import "common/variables"; + +/** Import Bootstrap */ +@import "bootstrap/scss/bootstrap"; +@import "bootstrap-icons/font/bootstrap-icons.scss"; + +/** Import highlight.js */ +@import "highlight.js/scss/github-dark-dimmed"; + +/** Import KaTeX */ +@import "katex/dist/katex"; + +/** Import theme styles */ +@import "common/fonts"; +@import "common/global"; +@import "common/dark"; +@import "components/alerts"; +@import "components/buttons"; +@import "components/code"; +@import "components/details"; +@import "components/syntax"; +@import "components/comments"; +@import "components/forms"; +@import "components/images"; +@import "components/mermaid"; +@import "components/search"; +@import "components/tables"; +@import "layouts/footer"; +@import "layouts/header"; +@import "layouts/pages"; +@import "layouts/posts"; +@import "layouts/sidebar"; +@import "custom"; diff --git a/docs/assets/scss/common/_dark.scss b/docs/assets/scss/common/_dark.scss new file mode 100644 index 000000000..4694fd540 --- /dev/null +++ b/docs/assets/scss/common/_dark.scss @@ -0,0 +1,572 @@ +/** Theme variables */ + +// Source: https://material.io/design/color/dark-theme.html + +$body-bg-dark: $gray-900; +$body-overlay-dark: darken($body-bg-dark, 2.5%); + +/* +$border-dark: darken($body-bg-dark, 2.5%); +*/ +$border-dark: $gray-800; +$body-color-dark: $gray-300; +$dots-dark: darken($body-color-dark, 50%); + +$link-color-dark: $blue-300; +$button-color-dark: $link-color-dark; +$focus-color-dark: lighten($link-color-dark, 2.5%); + +$navbar-dark-color: $body-color-dark; +$navbar-dark-hover-color: $link-color-dark; +$navbar-dark-active-color: $link-color-dark; + +/** Theme styles */ + +[data-dark-mode] body { + background: $body-bg-dark; + color: $body-color-dark; +} + +[data-dark-mode] body a { + color: $link-color-dark; +} + +[data-dark-mode] body a.text-body { + color: $body-color-dark !important; +} + +[data-dark-mode] body .btn-primary { + @include button-variant($button-color-dark, $button-color-dark); + + color: $body-bg-dark !important; +} + +[data-dark-mode] body .btn-outline-primary { + @include button-outline-variant($button-color-dark, $button-color-dark); + + color: $link-color-dark; +} + +[data-dark-mode] body .btn-outline-primary:hover { + color: $body-bg-dark; +} + +[data-dark-mode] body .btn-doks-light { + color: $navbar-dark-color; +} + +[data-dark-mode] body .show > .btn-doks-light, +[data-dark-mode] body .btn-doks-light:hover, +[data-dark-mode] body .btn-doks-light:active { + color: $link-color-dark; +} + +[data-dark-mode] body .btn-menu svg { + color: $body-color-dark; +} + +[data-dark-mode] body .doks-sidebar-toggle { + color: $navbar-dark-color; +} + +[data-dark-mode] body .btn-menu:hover, +[data-dark-mode] body .btn-doks-light:hover, +[data-dark-mode] body .doks-sidebar-toggle:hover { + background: $body-overlay-dark; +} + +/* +[data-dark-mode] body .dropdown-menu { + @extend .dropdown-menu-dark; +} +*/ + +[data-dark-mode] body .navbar, +[data-dark-mode] body .doks-subnavbar { + background-color: rgba(33, 37, 41, 0.95); + border-bottom: 1px solid $border-dark; +} + +[data-dark-mode] body.home .navbar { + border-bottom: 0; +} + +[data-dark-mode] body .offcanvas-header { + border-bottom: 1px solid $gray-800; +} + +[data-dark-mode] body .offcanvas .nav-link { + color: $body-color-dark; +} + +[data-dark-mode] body .offcanvas .nav-link:hover, +[data-dark-mode] body .offcanvas .nav-link:focus { + color: $link-color-dark; +} + +[data-dark-mode] body .offcanvas .nav-link.active { + color: $link-color-dark; +} + +[data-dark-mode] body .navbar-light .navbar-brand { + color: $navbar-dark-color !important; +} + +[data-dark-mode] body .navbar-light .navbar-nav .nav-link { + color: $navbar-dark-color; +} + +[data-dark-mode] body .navbar-light .navbar-nav .nav-link:hover, +[data-dark-mode] body .navbar-light .navbar-nav .nav-link:focus { + color: $navbar-dark-hover-color; +} + +[data-dark-mode] body .navbar-light .navbar-nav .nav-link.disabled { + color: $navbar-dark-disabled-color; +} + +[data-dark-mode] body .navbar-light .navbar-nav .show > .nav-link, +[data-dark-mode] body .navbar-light .navbar-nav .active > .nav-link, +[data-dark-mode] body .navbar-light .navbar-nav .nav-link.show, +[data-dark-mode] body .navbar-light .navbar-nav .nav-link.active { + color: $navbar-dark-active-color; +} + +[data-dark-mode] body .navbar-light .navbar-text { + color: $navbar-dark-color; +} + +[data-dark-mode] body .alert-primary a { + color: $body-bg-dark; +} + +[data-dark-mode] body .alert-doks { + background: $body-overlay-dark; + color: $body-color-dark; +} + +[data-dark-mode] body .alert-doks a { + color: $link-color-dark; +} + +[data-dark-mode] body .page-links a { + color: $body-color-dark; +} + +[data-dark-mode] body .btn-toggle-nav a { + color: $body-color-dark; +} + +[data-dark-mode] body .showcase-meta a { + color: $body-color-dark; +} + +[data-dark-mode] body .showcase-meta a:hover, +[data-dark-mode] body .showcase-meta a:focus { + color: $link-color-dark; +} + +[data-dark-mode] body .docs-link:hover, +[data-dark-mode] body .docs-link.active, +[data-dark-mode] body .page-links a:hover { + text-decoration: none; + color: $link-color-dark; +} + +[data-dark-mode] body .btn-toggle { + color: $body-color-dark; + background-color: transparent; + border: 0; +} + +[data-dark-mode] body .btn-toggle:hover, +[data-dark-mode] body .btn-toggle:focus { + color: $body-color-dark; +} + +[data-dark-mode] body .btn-toggle::before { + width: 1.25em; + line-height: 0; + content: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='rgba%28222, 226, 230, 0.75%29' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M5 14l6-6-6-6'/%3e%3c/svg%3e"); + transition: transform 0.35s ease; + transform-origin: 0.5em 50%; + margin-bottom: 0.125rem; +} + +[data-dark-mode] body .btn-toggle[aria-expanded="true"] { + color: $body-color-dark; +} + +[data-dark-mode] body .btn-toggle[aria-expanded="true"]::before { + transform: rotate(90deg); +} + +[data-dark-mode] body .btn-toggle-nav a:hover, +[data-dark-mode] body .btn-toggle-nav a:focus { + color: $link-color-dark; +} + +[data-dark-mode] body .btn-toggle-nav a.active { + color: $link-color-dark; +} + +[data-dark-mode] body .navbar-light .navbar-text a { + color: $navbar-dark-active-color; +} + +[data-dark-mode] body .docs-links h3.sidebar-link a, +[data-dark-mode] body .page-links h3.sidebar-link a { + color: $body-color-dark; +} + +[data-dark-mode] body .navbar-light .navbar-text a:hover, +[data-dark-mode] body .navbar-light .navbar-text a:focus { + color: $navbar-dark-active-color; +} + +[data-dark-mode] body .navbar .btn-link { + color: $navbar-dark-color; +} + +[data-dark-mode] body .content .btn-link { + color: $link-color-dark; +} + +[data-dark-mode] body .content .btn-link:hover { + color: $link-color-dark; +} + +[data-dark-mode] body .content img[src^="https://latex.codecogs.com/svg.latex"] { + filter: invert(1); +} + +[data-dark-mode] body .navbar .btn-link:hover { + color: $navbar-dark-hover-color; +} + +[data-dark-mode] body .navbar .btn-link:active { + color: $navbar-dark-active-color; +} + +[data-dark-mode] body .form-control.is-search { + background: $body-overlay-dark; + border: 1px solid transparent; + color: $gray-300; + + /* + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 24 24' fill='none' stroke='%236c757d' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-search'%3E%3Ccircle cx='11' cy='11' r='8'%3E%3C/circle%3E%3Cline x1='21' y1='21' x2='16.65' y2='16.65'%3E%3C/line%3E%3C/svg%3E"); + background-repeat: no-repeat; + background-position: right calc(0.375em + 0.1875rem) center; + background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); + */ +} + +[data-dark-mode] body .form-control.is-search:focus { + border: 1px solid $link-color-dark; +} + +[data-dark-mode] body .doks-search::after { + color: $gray-300; + border: 1px solid $gray-700; +} + +[data-dark-mode] body .text-dark { + color: $body-color-dark !important; +} + +/* +[data-dark-mode] body .navbar-form::after { + color: $gray-600; + border: 1px solid $gray-800; +} +*/ + +[data-dark-mode] body .form-control { + color: $gray-300; +} + +[data-dark-mode] body .form-control::placeholder { + color: $gray-400; + opacity: 1; +} + +[data-dark-mode] body .border-top { + border-top: 1px solid $border-dark !important; +} + +@include media-breakpoint-up(lg) { + [data-dark-mode] body .docs-sidebar { + order: 0; + border-right: 1px solid $border-dark; + } +} + +[data-dark-mode] body .docs-navigation { + border-top: 1px solid $border-dark; +} + +[data-dark-mode] body pre code::-webkit-scrollbar-thumb { + background: $gray-400; +} + +[data-dark-mode] body code:not(.hljs) { + background: $body-overlay-dark; + color: $body-color-dark; +} + +[data-dark-mode] body pre code:hover { + scrollbar-width: thin; + scrollbar-color: $border-dark transparent; +} + +[data-dark-mode] body pre code::-webkit-scrollbar-thumb:hover { + background: $gray-500; +} + +[data-dark-mode] body blockquote { + border-left: 3px solid $border-dark; +} + +[data-dark-mode] body .footer { + border-top: 1px solid $border-dark; +} + +[data-dark-mode] body .docs-links, +[data-dark-mode] body .docs-toc { + scrollbar-width: thin; + scrollbar-color: $body-bg-dark $body-bg-dark; +} + +[data-dark-mode] body .docs-links::-webkit-scrollbar, +[data-dark-mode] body .docs-toc::-webkit-scrollbar { + width: 5px; +} + +[data-dark-mode] body .docs-links::-webkit-scrollbar-track, +[data-dark-mode] body .docs-toc::-webkit-scrollbar-track { + background: $body-bg-dark; +} + +[data-dark-mode] body .docs-links::-webkit-scrollbar-thumb, +[data-dark-mode] body .docs-toc::-webkit-scrollbar-thumb { + background: $body-bg-dark; +} + +[data-dark-mode] body .docs-links:hover, +[data-dark-mode] body .docs-toc:hover { + scrollbar-width: thin; + scrollbar-color: $border-dark $body-bg-dark; +} + +[data-dark-mode] body .docs-links:hover::-webkit-scrollbar-thumb, +[data-dark-mode] body .docs-toc:hover::-webkit-scrollbar-thumb { + background: $border-dark; +} + +[data-dark-mode] body .docs-links::-webkit-scrollbar-thumb:hover, +[data-dark-mode] body .docs-toc::-webkit-scrollbar-thumb:hover { + background: $border-dark; +} + +[data-dark-mode] body .docs-links h3:not(:first-child) { + border-top: 1px solid $border-dark; +} + +[data-dark-mode] body a.docs-link { + color: $body-color-dark; +} + +[data-dark-mode] body .page-links li:not(:first-child) { + border-top: 1px dashed $border-dark; +} + +[data-dark-mode] body .card { + background: $body-bg-dark; + border: 1px solid $border-dark; +} + +[data-dark-mode] body .card.bg-light { + background: $body-overlay-dark !important; +} + +[data-dark-mode] body .navbar .menu-icon .navicon { + background: $navbar-dark-color; +} + +[data-dark-mode] body .navbar .menu-icon .navicon::before, +[data-dark-mode] body .navbar .menu-icon .navicon::after { + background: $navbar-dark-color; +} + +[data-dark-mode] body .logo-light { + display: none !important; +} + +[data-dark-mode] body .logo-dark { + display: inline-block !important; +} + +[data-dark-mode] body .bg-light { + background: darken($body-bg-dark, 1.5%) !important; +} + +[data-dark-mode] body .bg-dots { + background-image: radial-gradient($dots-dark 15%, transparent 15%); +} + +[data-dark-mode] body .text-muted { + color: darken($body-color-dark, 7.5%) !important; +} + +[data-dark-mode] body .alert-primary { + background: $link-color-dark; + color: $body-bg-dark; +} + +[data-dark-mode] body .figure-caption { + color: $body-color-dark; +} + +[data-dark-mode] body table { + @extend .table-dark; +} + +[data-dark-mode] body .copy-status::after { + content: "Copy"; + display: block; + color: $body-color-dark; +} + +[data-dark-mode] body .copy-status:hover::after { + content: "Copy"; + display: block; + color: $link-color-dark; +} + +[data-dark-mode] body .copy-status:focus::after, +[data-dark-mode] body .copy-status:active::after { + content: "Copied"; + display: block; + color: $link-color-dark; +} + +/* +[data-dark-mode] body .dropdown-toggle:focus, +[data-dark-mode] body .doks-sidebar-toggle:focus { + box-shadow: 0 0 0 0.2rem $focus-color-dark; +} +*/ + +[data-dark-mode] body .offcanvas { + background-color: $body-bg-dark; +} + +[data-dark-mode] body .btn-close { + background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9IiNkZWUyZTYiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBjbGFzcz0iZmVhdGhlciBmZWF0aGVyLXgiPjxsaW5lIHgxPSIxOCIgeTE9IjYiIHgyPSI2IiB5Mj0iMTgiPjwvbGluZT48bGluZSB4MT0iNiIgeTE9IjYiIHgyPSIxOCIgeTI9IjE4Ij48L2xpbmU+PC9zdmc+"); + background-size: 1.5rem; +} + +@include media-breakpoint-up(md) { + [data-dark-mode] body .alert-dismissible .btn-close { + background-size: 1.25rem; + } +} + +/* +[data-dark-mode] body .btn-close:focus { + box-shadow: 0 0 0 0.2rem $focus-color-dark; +} +*/ + +[data-dark-mode] .dropdown-item { + color: $body-bg-dark; +} + +[data-dark-mode] body hr.text-black-50 { + color: $gray-600 !important; +} + +[data-dark-mode] body .email-form .form-control { + background: $body-overlay-dark; + border: 1px solid transparent; +} + +[data-dark-mode] body .email-form .form-control:focus { + border: 1px solid $link-color-dark; +} + +[data-dark-mode] .page-link { + color: $link-color-dark; + background-color: transparent; + border: $pagination-border-width solid $border-dark; + + &:hover { + color: $body-bg-dark; + background-color: $body-color-dark; + border-color: $body-color-dark; + } + + &:focus { + color: $body-bg-dark; + background-color: $body-color-dark; + } +} + +[data-dark-mode] .page-item { + &.active .page-link { + color: $body-bg-dark; + + @include gradient-bg($link-color-dark); + + border-color: $link-color-dark; + } + + &.disabled .page-link { + color: $pagination-disabled-color; + background-color: $body-overlay-dark; + border-color: $border-dark; + } +} + +[data-dark-mode] .dropdown-menu { + background: $body-overlay-dark; +} + +[data-dark-mode] .dropdown-menu .dropdown-item { + color: $body-color-dark; +} + +[data-dark-mode] .dropdown-menu .dropdown-item:hover { + color: $link-color-dark; + background: $body-bg-dark; +} + +[data-dark-mode] .dropdown-menu .dropdown-item.active, +[data-dark-mode] .dropdown-menu .dropdown-item:focus { + color: $link-color-dark; + background: $body-bg-dark; +} + +[data-dark-mode] .doks-navbar .dropdown-item.current, +[data-dark-mode] .doks-subnavbar .dropdown-item.current { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23dee2e6' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e"); + background-repeat: no-repeat; + background-position: right 1rem top 0.6rem; + background-size: 0.75rem 0.75rem; +} + +[data-dark-mode] details { + border: 1px solid $border-dark; +} + +[data-dark-mode] summary:hover { + background: $body-overlay-dark; +} + +[data-dark-mode] details[open] > summary { + border-bottom: 1px solid $border-dark; +} + +[data-dark-mode] details summary::before { + content: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='rgba%28222, 226, 230, 0.75%29' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M5 14l6-6-6-6'/%3e%3c/svg%3e"); +} diff --git a/docs/assets/scss/common/_fonts.scss b/docs/assets/scss/common/_fonts.scss new file mode 100644 index 000000000..9bbc6eee5 --- /dev/null +++ b/docs/assets/scss/common/_fonts.scss @@ -0,0 +1,101 @@ +/* jost-regular - latin */ +@font-face { + font-family: Jost; + font-style: normal; + font-weight: 400; + font-display: swap; + src: + // Google Fonts Jost + local("Jost Regular Regular"), // Full Name + local("Jost-Regular"), // PostScript name + // indestructible Jost* + local("Jost* Book"), + local("Jost-Book"), + url("fonts/vendor/jost/jost-v4-latin-regular.woff2") format("woff2"), + url("fonts/vendor/jost/jost-v4-latin-regular.woff") format("woff"); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ +} + +/* jost-500 - latin */ +@font-face { + font-family: Jost; + font-style: normal; + font-weight: 500; + font-display: swap; + src: + // Google Fonts Jost + local("Jost Regular Medium"), + local("JostRoman-Medium"), + // indestructible Jost* + local("Jost* Medium"), + local("Jost-Medium"), + url("fonts/vendor/jost/jost-v4-latin-500.woff2") format("woff2"), + url("fonts/vendor/jost/jost-v4-latin-500.woff") format("woff"); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ +} + +/* jost-700 - latin */ +@font-face { + font-family: Jost; + font-style: normal; + font-weight: 700; + font-display: swap; + src: + // Google Fonts Jost + local("Jost Regular Bold"), + local("JostRoman-Bold"), + // indestructible Jost* + local("Jost* Bold"), + local("Jost-Bold"), + url("fonts/vendor/jost/jost-v4-latin-700.woff2") format("woff2"), + url("fonts/vendor/jost/jost-v4-latin-700.woff") format("woff"); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ +} + +/* jost-italic - latin */ +@font-face { + font-family: Jost; + font-style: italic; + font-weight: 400; + font-display: swap; + src: + // Google Fonts Jost + local("Jost Italic Italic"), + local("Jost-Italic"), + // indestructible Jost* + local("Jost* BookItalic"), + local("Jost-BookItalic"), + url("fonts/vendor/jost/jost-v4-latin-italic.woff2") format("woff2"), + url("fonts/vendor/jost/jost-v4-latin-italic.woff") format("woff"); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ +} + +/* jost-500italic - latin */ +@font-face { + font-family: Jost; + font-style: italic; + font-weight: 500; + font-display: swap; + src: + // Google Fonts Jost + local("Jost Italic Medium Italic"), + local("JostItalic-Medium"), + // indestructible Jost* + local("Jost* Medium Italic"), + local("Jost-MediumItalic"), + url("fonts/vendor/jost/jost-v4-latin-500italic.woff2") format("woff2"), + url("fonts/vendor/jost/jost-v4-latin-500italic.woff") format("woff"); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ +} + +/* jost-700italic - latin */ +@font-face { + font-family: Jost; + font-style: italic; + font-weight: 700; + font-display: swap; + src: + // Google Fonts Jost + local("Jost Italic Bold Italic"), + local("JostItalic-Bold"), + // indestructible Jost* + local("Jost* Bold Italic"), + local("Jost-BoldItalic"), + url("fonts/vendor/jost/jost-v4-latin-700italic.woff2") format("woff2"), + url("fonts/vendor/jost/jost-v4-latin-700italic.woff") format("woff"); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ +} diff --git a/docs/assets/scss/common/_global.scss b/docs/assets/scss/common/_global.scss new file mode 100644 index 000000000..8fa8b2f93 --- /dev/null +++ b/docs/assets/scss/common/_global.scss @@ -0,0 +1,312 @@ +.contributors .content, +.blog .content, +.page .content, +.error404 .content, +.docs.list .content, +.tutorial.list .content, +.showcase.list .content { + padding-top: 1rem; + padding-bottom: 3rem; +} + +.content img { + max-width: 100%; +} + +h1, +h2, +h3, +h4, +h5, +h6, +.h1, +.h2, +.h3, +.h4, +.h5, +.h6 { + margin: 2rem 0 1rem; +} + +.offcanvas-header { + border-bottom: 1px solid $gray-300; + padding-top: 1.0625rem; + padding-bottom: 0.8125rem; +} + +h5.offcanvas-title { + margin: 0; +} + +body.docs { + padding-top: 0 !important; +} + +@include media-breakpoint-up(md) { + body { + font-size: $font-size-md; + + /* + padding-top: 4rem !important; + */ + } + + h1, + h2, + h3, + h4, + h5, + h6, + .h1, + .h2, + .h3, + .h4, + .h5, + .h6 { + margin-bottom: 1.125rem; + } +} + +.home h1 { + /* font-size: calc(1.375rem + 1.5vw); */ + font-size: calc(1.875rem + 1.5vw); +} + +a:hover, +a:focus { + text-decoration: underline; +} + +a.btn:hover, +a.btn:focus { + text-decoration: none; +} + +.section { + padding-top: 5rem; + padding-bottom: 5rem; +} + +.section-md { + padding-top: 3rem; + padding-bottom: 3rem; +} + +.section-sm { + padding-top: 1rem; + padding-bottom: 1rem; +} + +/* +.section svg { + display: inline-block; + width: 2rem; + height: 2rem; + vertical-align: text-top; +} +*/ + +/* +body { + padding-top: 3.5625rem; +} +*/ + +.docs-sidebar { + order: 2; +} + +@include media-breakpoint-up(lg) { + .docs-sidebar { + order: 0; + border-right: 1px solid $gray-200; + } + + @supports ((position:-webkit-sticky) or (position:sticky)) { + .docs-sidebar { + position: -webkit-sticky; + position: sticky; + top: 4rem; + z-index: 1000; + height: calc(100vh - 4rem); + } + } +} + +@include media-breakpoint-up(xl) { + .docs-sidebar { + flex: 0 1 320px; + } +} + +.docs-links { + padding-bottom: 5rem; +} + +@include media-breakpoint-up(lg) { + @supports ((position: -webkit-sticky) or (position: sticky)) { + .docs-links { + max-height: calc(100vh - 4rem); + overflow-y: scroll; + } + } +} + +@include media-breakpoint-up(lg) { + .docs-links { + display: block; + width: auto; + margin-right: -1.5rem; + padding-bottom: 4rem; + } +} + +.docs-toc { + order: 2; +} + +@supports ((position:-webkit-sticky) or (position:sticky)) { + .docs-toc { + position: -webkit-sticky; + position: sticky; + top: 4rem; + height: calc(100vh - 4rem); + overflow-y: auto; + } +} + +.docs-content { + padding-bottom: 3rem; + order: 1; +} + +.docs-navigation { + border-top: 1px solid $gray-200; + margin-top: 2rem; + margin-bottom: 0; + padding-top: 2rem; +} + +.docs-navigation a { + font-size: $font-size-base * 0.9; +} + +@include media-breakpoint-up(lg) { + .docs-navigation { + margin-bottom: -1rem; + } + + .docs-navigation a { + font-size: $font-size-base; + } +} + +.navbar a:hover, +.navbar a:focus { + text-decoration: none; +} + +#TableOfContents ul { + padding-left: 0; + list-style: none; +} + +::selection { + background: rgba(212, 53, 159, 0.2); +} + +.bg-dots { + background-image: radial-gradient($gray-300 15%, transparent 15%); + background-position: 0 0; + background-size: 1rem 1rem; + -webkit-mask: linear-gradient(to top, #fff, transparent); + mask: linear-gradient(to top, #fff, transparent); + width: 100%; + height: 9rem; + margin-top: -10rem; + z-index: -1; +} + +.bg-dots-md { + margin-top: -11rem; +} + +.bg-dots-lg { + margin-top: -12rem; +} + +.confkey-type { + background-color: $purple; +} + +.confkey-default { + background-color: $blue; +} + +.confkey-required { + background-color: $red; +} + +.confkey-notrequired { + background-color: $green; +} + +.confkey-situational { + background-color: $orange; +} + +.rs-not-started { + background-color: $red; +} + +.rs-complete { + background-color: $green; +} + +.rs-started { + background-color: $blue; +} + +.rs-waiting { + background-color: $yellow; +} + +.rs-version { + background-color: $purple; +} + +// https://fossheim.io/writing/posts/css-text-gradient/ +.gradient-text { + background-color: $primary; + background-image: linear-gradient(90deg, $primary, $blue-300 50%, $pink-500); + background-size: 100%; + background-repeat: repeat; + -webkit-background-clip: text; + -moz-background-clip: text; + -webkit-text-fill-color: transparent; + -moz-text-fill-color: transparent; +} + +.katex { + font-size: $font-size-md; +} + +.card-bar { + border-top: 4px solid; + border-image-source: linear-gradient(90deg, $primary, #8ed6fb 50%, #d32e9d); + border-image-slice: 1; +} + +.modal-backdrop { + background-color: #fff; +} + +.modal-backdrop.show { + opacity: 0.7; +} + +@include media-breakpoint-up(md) { + .modal-backdrop.show { + opacity: 0; + } +} diff --git a/docs/assets/scss/common/_variables.scss b/docs/assets/scss/common/_variables.scss new file mode 100644 index 000000000..77f538454 --- /dev/null +++ b/docs/assets/scss/common/_variables.scss @@ -0,0 +1,200 @@ +// Color system + +$white: #fff; +$gray-100: #f8f9fa; +$gray-200: #e9ecef; +$gray-300: #dee2e6; +$gray-400: #ced4da; +$gray-500: #adb5bd; +$gray-600: #6c757d; +$gray-700: #495057; +$gray-800: #343a40; +$gray-900: #212529; +$black: #000; + +$yellow: #ffe000; +$black: #1d2d35; +$beige: #fbf7f0; + +// $red: #e55235; +$purple: #5d2f86; +$brown: #aa9c84; + +$blue-300: #8ed6fb; +$pink-100: #fcfaff; +$pink-500: #d32e9d; + +$primary: $purple; + +$color-btn-bg: $pink-500; +$color-btn-border: darken($pink-500, 5%); +$color-btn-text: $white; + +// Options +// +// Quickly modify global styling by enabling or disabling optional features. + +$enable-caret: true; +$enable-rounded: true; +$enable-shadows: false; +$enable-gradients: false; +$enable-transitions: true; +$enable-reduced-motion: true; +$enable-smooth-scroll: true; +$enable-grid-classes: true; +$enable-button-pointers: true; +$enable-rfs: true; +$enable-validation-icons: true; +$enable-negative-margins: true; +$enable-deprecation-messages: true; +$enable-important-utilities: true; + +/** Bootstrap navbar fix (https://git.io/fADqW) */ +$navbar-dark-toggler-icon-bg: none; +$navbar-light-toggler-icon-bg: none; + +// Options +// +// Quickly modify global styling by enabling or disabling optional features. + +// $enable-responsive-font-sizes: true; + +// Body +// +// Settings for the `` element. + +$body-bg: $white; +$body-color: $black; + +// Links +// +// Style anchor elements. + +$link-color: $primary; +$link-decoration: none; + +// Grid containers +// +// Define the breakpoints for different screen sizes. +$grid-breakpoints: ( + xs: 0, + sm: 576px, + md: 768px, + lg: 992px, + xl: 1200px, + xxl: 2380px +); + +// Define the maximum width of `.container` for different screen sizes. + +$container-max-widths: ( + sm: 540px, + md: 720px, + lg: 960px, + xl: 1240px, + xxl: 2240px +); + +@include _assert-ascending($container-max-widths, "$container-max-widths"); + +// Grid columns +// +// Set the number of columns and specify the width of the gutters. + +$grid-columns: 16; +$grid-gutter-width: 48px; +$grid-row-columns: 6; + +// Components +// +// Define common padding and border radius sizes and more. + +$border-color: $gray-200; + +// Typography +// +// Font, line-height, and color for body text, headings, and more. + +// stylelint-disable value-keyword-case +$font-family-sans-serif: "Jost", -apple-system, blinkmacsystemfont, "Segoe UI", roboto, "Helvetica Neue", arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; +$font-family-monospace: sfmono-regular, menlo, monaco, consolas, "Liberation Mono", "Courier New", monospace; +$font-family-base: $font-family-sans-serif; +// stylelint-enable value-keyword-case + +$font-size-base: 1rem; // Assumes the browser default, typically `16px` +$font-size-xl: $font-size-base * 1.375; +$font-size-lg: $font-size-base * 1.25; +$font-size-md: $font-size-base * 1.125; +$font-size-sm: $font-size-base * 0.875; + +// $line-height-base: 1.5; + +$headings-font-family: null; +$headings-font-weight: 700; + +$lead-font-weight: 400; + +// Spacing +// +// Control the default styling of most Bootstrap elements by modifying these +// variables. Mostly focused on spacing. +// You can add more entries to the $spacers map, should you need more variation. + +$spacer: 1rem; + +// Navbar + +$navbar-padding-y: $spacer / 2; +$navbar-padding-x: null; + +$navbar-nav-link-padding-x: 0.5rem; + +$navbar-light-color: $black; +$navbar-light-hover-color: $primary; +$navbar-light-active-color: $primary; + +// Cards + +$card-border-color: $gray-200; + +// Alerts +// +// Define alert colors, border radius, and padding. + +$alert-padding-y: $spacer; +$alert-padding-x: $spacer * 1.5; +$alert-margin-bottom: 0; +$alert-border-radius: 0; +$alert-link-font-weight: $headings-font-weight; +$alert-border-width: 0; + +$alert-bg-scale: 0; +$alert-border-scale: 0; +$alert-color-scale: 0; + +// docsearch +$dropdown-config: ( + main-color: $purple, + layout-type: normal, + layout-width: normal, + layout-alignment: align, + background-color: $white, + border-radius: 4, + border-width: 1, + border-color: $gray-200, + box-shadow: none, + branding-position: bottom, + spacing: normal, + include-desc: yes, + background-category-header: $white, + font-size: normal, + header-color: $black, + title-color: $black, + subtitle-color: $black, + text-color: $black, + highlight-color: $purple, + highlight-opacity: 0.1, + highlight-type: underline +); + +$input-btn-focus-width: 0; diff --git a/docs/assets/scss/components/_alerts.scss b/docs/assets/scss/components/_alerts.scss new file mode 100644 index 000000000..0e4ed8344 --- /dev/null +++ b/docs/assets/scss/components/_alerts.scss @@ -0,0 +1,164 @@ +.alert { + font-family: $font-family-monospace; + font-size: $font-size-sm; +} + +.alert-icon { + margin-right: 0.75rem; +} + +.docs main .alert { + margin: 2rem -1.5rem; +} + +.alert .alert-link { + text-decoration: underline; +} + +.alert-doks { + background: $beige; + color: $black; +} + +/* +.alert-light { + color: #215888; + background: linear-gradient(-45deg, rgb(212, 245, 255), rgb(234, 250, 255), rgb(234, 250, 255), #d3f6ef); +} + +.alert-light .alert-link { + color: #215888; +} +*/ + +.alert-white { + background-color: rgba(255, 255, 255, 0.95); +} + +.alert-primary { + color: $white; + background-color: $primary; +} + +.alert a { + text-decoration: underline; +} + +.alert-primary .alert-link { + color: $white; +} + +/* +.alert-primary { + color: #084298; + background-color: #cfe2ff; + border-color: #b6d4fe; +} + +.alert-primary .alert-link { + color: #06357a; +} +*/ + +.alert-secondary { + color: #41464b; + background-color: #e2e3e5; + border-color: #d3d6d8; +} + +.alert-secondary .alert-link { + color: #34383c; +} + +.alert-success { + color: #0f5132; + background-color: #d1e7dd; + border-color: #badbcc; +} + +.alert-success .alert-link { + color: #0c4128; +} + +.alert-info { + color: #055160; + background-color: #cff4fc; + border-color: #b6effb; +} + +.alert-info .alert-link { + color: #04414d; +} + +.alert-warning { + color: #664d03; + background-color: #fff3cd; + border-color: #ffecb5; +} + +.alert-warning .alert-link { + color: #523e02; +} + +.alert-danger { + color: #842029; + background-color: #f8d7da; + border-color: #f5c2c7; +} + +.alert-danger .alert-link { + color: #6a1a21; +} + +.alert-light { + color: #636464; + background-color: #fefefe; + border-color: #fdfdfe; +} + +.alert-light .alert-link { + color: #4f5050; +} + +.alert-dark { + color: #141619; + background-color: #d3d3d4; + border-color: #bcbebf; +} + +.alert-dark .alert-link { + color: #101214; +} + +.alert .alert-link:hover, +.alert .alert-link:focus { + text-decoration: none; +} + +.alert-dismissible .btn-close { + position: absolute; + top: 50%; + transform: translateY(-50%); + right: 1rem; + z-index: 2; + padding: 0.5rem; + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='32' height='32' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-x'%3E%3Cline x1='18' y1='6' x2='6' y2='18'%3E%3C/line%3E%3Cline x1='6' y1='6' x2='18' y2='18'%3E%3C/line%3E%3C/svg%3E"); + background-size: 1.5rem; + filter: invert(1) grayscale(100%) brightness(200%); +} + +@include media-breakpoint-up(md) { + .alert-dismissible .btn-close { + background-size: 1.25rem; + } +} + +[data-global-alert="closed"] #announcement { + display: none; +} + +.alert code { + background: darken($beige, 5%); + color: $black; + padding: 0.25rem 0.5rem; +} diff --git a/docs/assets/scss/components/_buttons.scss b/docs/assets/scss/components/_buttons.scss new file mode 100644 index 000000000..235d6ea19 --- /dev/null +++ b/docs/assets/scss/components/_buttons.scss @@ -0,0 +1,253 @@ +.navbar .btn-link { + color: $navbar-light-color; + padding: 0.4375rem 0; +} + +#mode { + padding-right: 0.25rem; + padding-left: 0.25rem; + margin-right: -0.25rem; +} + +.btn-link:focus { + outline: 0; + box-shadow: none; +} + +#navigation { + margin-left: 1.25rem; +} + +@include media-breakpoint-up(md) { + #mode { + margin-left: 1.125rem; + margin-right: -0.375rem; + } + + .navbar .btn-link { + padding: 0.5625em 0.25rem 0.5rem 0.125rem; + } +} + +.navbar .btn-link:hover { + color: $navbar-light-hover-color; +} + +.navbar .btn-link:active { + color: $navbar-light-active-color; +} + +body .toggle-dark { + display: block; +} + +body .toggle-light { + display: none; +} + +[data-dark-mode] body .toggle-light { + display: block; +} + +[data-dark-mode] body .toggle-dark { + display: none; +} + +pre { + position: relative; +} + +@include media-breakpoint-down(md) { + .btn-copy { + display: none; + } +} + +.btn-copy { + transition: opacity 0.3s ease-in-out; + visibility: hidden !important; + position: absolute; + right: 0.25rem; + top: 0.25rem; + z-index: 10; + font-family: $font-family-sans-serif; + font-size: $font-size-sm; + padding: 0.25rem 0.5rem; + color: $color-btn-text; + background-color: $color-btn-bg; + border-color: $color-btn-border; +} + +.btn-copy:hover { + color: $color-btn-text; + background-color: lighten($color-btn-bg, 5%); + border-color: lighten($color-btn-border, 15%); +} + +.btn-copy:focus { + color: $color-btn-text; + background-color: $color-btn-bg; + border-color: lighten($color-btn-border, 15%); + box-shadow: none; +} + +.btn-copy:active, +.btn-copy.active { + color: $color-btn-text; + background-color: $color-btn-bg; + border-color: lighten($color-btn-border, 15%); +} + +.btn-copy:active:focus, +.btn-copy.active:focus { + box-shadow: none; +} + +@include media-breakpoint-up(md) { + pre:hover .btn-copy { + visibility: visible !important; + } +} + +.btn-copy::after { + content: "Copy"; + display: block; + color: $color-btn-text; +} + +.btn-copy:hover::after { + content: "Copy"; + display: block; + color: $color-btn-text; +} + +.btn-copy:focus::after, +.btn-copy:active::after { + content: "Copied"; + display: block; + color: $color-btn-text; +} + +.collapsible-sidebar { + margin: 2.125rem 0; +} + +.btn-toggle { + display: inline-flex; + align-items: center; + padding: 0.25rem 0.5rem 0.25rem 0; + font-weight: $headings-font-weight; + font-size: $font-size-base; + text-transform: uppercase; + color: $body-color; + background-color: transparent; + border: 0; +} + +.btn-toggle:hover, +.btn-toggle:focus { + color: $body-color; + background-color: transparent; + outline: 0; + box-shadow: none; +} + +.btn-toggle::before { + width: 1.25em; + line-height: 0; + content: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='rgba%2829, 45, 53, 0.75%29' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M5 14l6-6-6-6'/%3e%3c/svg%3e"); + transition: transform 0.35s ease; + transform-origin: 0.5em 50%; + margin-bottom: 0.125rem; +} + +.btn-toggle[aria-expanded="true"] { + color: $body-color; +} + +.btn-toggle[aria-expanded="true"]::before { + transform: rotate(90deg); +} + +.btn-toggle-nav a { + display: inline-flex; + padding: 0.1875rem 0.5rem; + margin-top: 0.125rem; + margin-left: 1.25rem; + text-decoration: none; +} + +.btn-toggle-nav a:hover, +.btn-toggle-nav a:focus { + background-color: transparent; + color: $link-color; +} + +.btn-toggle-nav a.active { + color: $link-color; +} + +.doks-navbar .dropdown-menu, +.doks-subnavbar .dropdown-menu { + font-size: 0.875rem; +} + +.doks-navbar .dropdown-item.current, +.doks-subnavbar .dropdown-item.current { + font-weight: 600; + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23292b2c' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e"); + background-repeat: no-repeat; + background-position: right 1rem top 0.6rem; + background-size: 0.75rem 0.75rem; +} + +.btn-close { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='32' height='32' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-x'%3E%3Cline x1='18' y1='6' x2='6' y2='18'%3E%3C/line%3E%3Cline x1='6' y1='6' x2='18' y2='18'%3E%3C/line%3E%3C/svg%3E"); + background-size: 1.5rem; +} + +.offcanvas-header .btn-close { + margin-right: 0 !important; +} + +.dropdown-toggle::after { + display: none; +} + +.dropdown-caret { + margin-left: -0.1875rem; + margin-right: -0.3125rem; +} + +.dropdown-menu.dropdown-menu-main { + width: 100%; +} + +@include media-breakpoint-up(md) { + .dropdown-menu.dropdown-menu-main { + width: auto; + } +} + +.dropdown-menu-main .dropdown-item { + color: inherit; + font-size: $font-size-base; + font-weight: 400; + text-decoration: none; +} + +.dropdown-menu-main .dropdown-item:hover { + background-color: transparent; + color: $primary; +} + +.dropdown-menu-main .dropdown-item.active { + color: $primary; + font-weight: 400; + text-decoration: none; + background-color: inherit; +} + +.dropdown-menu-main .dropdown-item.active:hover { + background-color: transparent; +} diff --git a/docs/assets/scss/components/_code.scss b/docs/assets/scss/components/_code.scss new file mode 100644 index 000000000..84ad2bca5 --- /dev/null +++ b/docs/assets/scss/components/_code.scss @@ -0,0 +1,66 @@ +pre, +code, +kbd, +samp { + font-family: $font-family-monospace; + font-size: $font-size-sm; + border-radius: $border-radius; +} + +code { + background: $beige; + color: $black; + padding: 0.25rem 0.5rem; +} + +pre { + margin: 2rem 0; +} + +pre code { + display: block; + overflow-x: auto; + line-height: $line-height-base; + padding: 1.25rem 1.5rem; + tab-size: 4; + scrollbar-width: thin; + scrollbar-color: transparent transparent; +} + +.hljs { + padding: 1.5rem !important; +} + +@include media-breakpoint-down(sm) { + pre, + code, + kbd, + samp { + border-radius: 0; + } + + pre { + margin: 2rem -1.5rem; + } +} + +pre code::-webkit-scrollbar { + height: 5px; +} + +pre code::-webkit-scrollbar-thumb { + background: $gray-400; +} + +pre code:hover { + scrollbar-width: thin; + scrollbar-color: $gray-500 transparent; +} + +pre code::-webkit-scrollbar-thumb:hover { + background: $gray-500; +} + +code.language-mermaid { + background: none; +} diff --git a/docs/assets/scss/components/_comments.scss b/docs/assets/scss/components/_comments.scss new file mode 100644 index 000000000..18f610c94 --- /dev/null +++ b/docs/assets/scss/components/_comments.scss @@ -0,0 +1,30 @@ +.comment-list { + @extend .list-unstyled; +} + +.comment-list ol { + list-style: none; +} + +.comment-form p { + @extend .form-group !optional; +} + +.comment-form input[type="text"], +.comment-form input[type="email"], +.comment-form input[type="url"], +.comment-form textarea { + @extend .form-control; +} + +.comment-form input[type="submit"] { + @extend .btn; + @extend .btn-secondary; +} + +blockquote { + margin-bottom: 1rem; + font-size: 1.25rem; + border-left: 3px solid $gray-300; + padding-left: 1rem; +} diff --git a/docs/assets/scss/components/_details.scss b/docs/assets/scss/components/_details.scss new file mode 100644 index 000000000..fb719d366 --- /dev/null +++ b/docs/assets/scss/components/_details.scss @@ -0,0 +1,77 @@ +details { + display: block; + border: 1px solid $gray-200; + border-radius: 0.25rem; + padding: 0.5rem 1rem 0; + margin: 0.5rem 0; +} + +/* +details summary { + &::marker { + content: ""; + } +} +*/ + +summary { + list-style: none; + display: inline-block; + width: calc(100% + 2rem); + margin: -0.5rem -1rem 0; + padding: 0.5rem 0.75rem; +} + +summary::-webkit-details-marker { + display: none; +} + +summary:hover { + background: $gray-100; +} + +details summary::before { + display: inline-block; + content: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='rgba%2829, 45, 53, 0.75%29' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M5 14l6-6-6-6'/%3e%3c/svg%3e"); + transition: transform 0.35s ease; + transform-origin: center center; + margin-right: 0.375rem; +} + +details[open] > summary::before { + transform: rotate(90deg); +} + +/* +details summary > * { + display: inline-block; +} +*/ + +details[open] { + padding: 0.5rem 1rem; +} + +details[open] > summary { + border-bottom: 1px solid $gray-300; + margin-bottom: 0.5rem; +} + +details h2, +details h3, +details h4 { + margin: 1rem 0 0.5rem; +} + +details p:last-child { + margin-bottom: 0; +} + +details ul, +details ol { + margin-bottom: 0; +} + +details pre { + margin: 0 0 1rem; +} diff --git a/docs/assets/scss/components/_forms.scss b/docs/assets/scss/components/_forms.scss new file mode 100644 index 000000000..9732838df --- /dev/null +++ b/docs/assets/scss/components/_forms.scss @@ -0,0 +1,19 @@ +/** Search form */ +.search-form { + @extend .form-inline !optional; +} + +.search-form label { + @extend .form-group; + + font-weight: normal; +} + +.search-form .search-field { + @extend .form-control; +} + +.search-form .search-submit { + @extend .btn; + @extend .btn-secondary; +} diff --git a/docs/assets/scss/components/_images.scss b/docs/assets/scss/components/_images.scss new file mode 100644 index 000000000..254eefa09 --- /dev/null +++ b/docs/assets/scss/components/_images.scss @@ -0,0 +1,48 @@ +figure { + margin: 2rem 0; +} + +.figure-caption { + margin: 0.25rem 0 0.75rem; +} + +figure.wide { + margin: 2rem -1.5rem; +} + +figure.wide .figure-caption { + margin: 0.25rem 1.5rem 0.75rem; +} + +@include media-breakpoint-up(md) { + figure.wide { + margin: 2rem -2.5rem; + } + + figure.wide .figure-caption { + margin: 0.25rem 2.5rem 0.75rem; + } +} + +@include media-breakpoint-up(lg) { + figure.wide { + margin: 2rem -5rem; + } + + figure.wide .figure-caption { + margin: 0.25rem 5rem 0.75rem; + } +} + +.blur-up { + filter: blur(5px); +} + +.blur-up.lazyloaded { + filter: unset; +} + +.img-simple { + margin-top: 0.375rem; + margin-bottom: 1.25rem; +} diff --git a/docs/assets/scss/components/_mermaid.scss b/docs/assets/scss/components/_mermaid.scss new file mode 100644 index 000000000..3ff24888a --- /dev/null +++ b/docs/assets/scss/components/_mermaid.scss @@ -0,0 +1,8 @@ +.mermaid { + margin: 1.5rem 0; + padding: 1.5rem; +} + +.mermaid svg { + height: auto; +} diff --git a/docs/assets/scss/components/_search.scss b/docs/assets/scss/components/_search.scss new file mode 100644 index 000000000..45ec2afff --- /dev/null +++ b/docs/assets/scss/components/_search.scss @@ -0,0 +1,81 @@ +.navbar-form { + position: relative; +} + +#suggestions { + position: absolute; + left: 0; + margin-top: 0.5rem; + width: calc(100vw - 3rem); + z-index: $zindex-dropdown; +} + +#suggestions a, +.suggestion__no-results { + padding: 0.75rem; + margin: 0 0.5rem; +} + +#suggestions a { + display: block; + text-decoration: none; +} + +#suggestions a:focus { + background: $gray-100; + outline: 0; +} + +#suggestions div:not(:first-child) { + border-top: 1px dashed $gray-200; +} + +#suggestions div:first-child { + margin-top: 0.5rem; +} + +#suggestions div:last-child { + margin-bottom: 0.5rem; +} + +#suggestions a:hover { + background: $gray-100; +} + +#suggestions span { + display: flex; + font-size: $font-size-base; +} + +.suggestion__title { + font-weight: $headings-font-weight; + color: $black; +} + +.suggestion__description, +.suggestion__no-results { + color: $gray-700; +} + +@include media-breakpoint-up(sm) { + #suggestions { + width: 31.125rem; + } + + #suggestions a { + display: flex; + } + + .suggestion__title { + width: 9rem; + padding-right: 1rem; + border-right: 1px solid $gray-200; + display: inline-block; + text-align: right; + } + + .suggestion__description { + width: 19rem; + padding-left: 1rem; + } +} diff --git a/docs/assets/scss/components/_syntax.scss b/docs/assets/scss/components/_syntax.scss new file mode 100644 index 000000000..2be315d95 --- /dev/null +++ b/docs/assets/scss/components/_syntax.scss @@ -0,0 +1,62 @@ +/* + +Based on Ascetic by (c) Ivan Sagalaev + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 1.25rem 1.5rem; + background: $beige; + color: $body-color; +} + +.hljs-string, +.hljs-variable, +.hljs-template-variable, +.hljs-symbol, +.hljs-bullet, +.hljs-section, +.hljs-addition, +.hljs-attribute, +.hljs-link { + color: $pink-500; +} + +.hljs-comment, +.hljs-quote, +.hljs-meta, +.hljs-deletion { + color: #888; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-section, +.hljs-name, +.hljs-type, +.hljs-strong { + font-weight: bold; +} + +.hljs-emphasis { + font-style: italic; +} + +[data-dark-mode] body .hljs { + background: $body-overlay-dark; + color: $body-color-dark; +} + +[data-dark-mode] body .hljs-string, +[data-dark-mode] body .hljs-variable, +[data-dark-mode] body .hljs-template-variable, +[data-dark-mode] body .hljs-symbol, +[data-dark-mode] body .hljs-bullet, +[data-dark-mode] body .hljs-section, +[data-dark-mode] body .hljs-addition, +[data-dark-mode] body .hljs-attribute, +[data-dark-mode] body .hljs-link { + color: $blue-300; +} diff --git a/docs/assets/scss/components/_tables.scss b/docs/assets/scss/components/_tables.scss new file mode 100644 index 000000000..b1f8c2e79 --- /dev/null +++ b/docs/assets/scss/components/_tables.scss @@ -0,0 +1,5 @@ +table { + @extend .table; + + margin: 3rem 0; +} diff --git a/docs/assets/scss/custom.scss b/docs/assets/scss/custom.scss new file mode 100644 index 000000000..dda718c20 --- /dev/null +++ b/docs/assets/scss/custom.scss @@ -0,0 +1,65 @@ +.text-orange { + --bs-text-opacity: 1; + + color: $orange; +} + +.icon-support-full { + @extend .bi; + @extend .bi-check-circle-fill; + @extend .text-success; +} + +[data-dark-mode] .icon-support-full { + @extend .bi; + @extend .bi-check-circle; + @extend .text-success; +} + +.icon-support-unknown { + @extend .bi; + @extend .bi-dash-circle-fill; + @extend .text-warning; +} + +[data-dark-mode] .icon-support-unknown { + @extend .bi; + @extend .bi-dash-circle; + @extend .text-warning; +} + +.icon-support-partial { + @extend .bi; + @extend .bi-exclamation-circle-fill; + @extend .text-orange; +} + +[data-dark-mode] .icon-support-partial { + @extend .bi; + @extend .bi-exclamation-circle; + @extend .text-orange; +} + +.icon-support-none { + @extend .bi; + @extend .bi-x-circle-fill; + @extend .text-danger; +} + +[data-dark-mode] .icon-support-none { + @extend .bi; + @extend .bi-x-circle; + @extend .text-danger; +} + +body code span.line.hl { + background: $orange; + display: block; + width: 100%; +} + +[data-dark-mode] body code span.line.hl { + background: $orange; + display: block; + width: 100%; +} diff --git a/docs/assets/scss/layouts/_footer.scss b/docs/assets/scss/layouts/_footer.scss new file mode 100644 index 000000000..7d2181144 --- /dev/null +++ b/docs/assets/scss/layouts/_footer.scss @@ -0,0 +1,20 @@ +.footer { + border-top: 1px solid $gray-200; + padding-top: 1.125rem; + padding-bottom: 1.125rem; +} + +.footer ul { + margin-bottom: 0; +} + +.footer li { + font-size: $font-size-sm; + margin-bottom: 0; +} + +@include media-breakpoint-up(md) { + .footer li { + font-size: $font-size-base; + } +} diff --git a/docs/assets/scss/layouts/_header.scss b/docs/assets/scss/layouts/_header.scss new file mode 100644 index 000000000..cb85c32c1 --- /dev/null +++ b/docs/assets/scss/layouts/_header.scss @@ -0,0 +1,445 @@ +.banner .nav li { + @extend .nav-item; +} + +.banner .nav a { + @extend .nav-link; +} + +.navbar-text { + margin-left: 1rem; +} + +.navbar-brand { + font-weight: $headings-font-weight; +} + +/* +.navbar-light .navbar-brand, +.navbar-light .navbar-brand:hover, +.navbar-light .navbar-brand:active { + color: $body-color; +} + +.navbar-light .navbar-nav .active .nav-link { + color: $primary; +} +*/ + +.navbar { + z-index: 1000; + background-color: rgba(255, 255, 255, 0.95); + border-bottom: 1px solid $gray-200; + + /* + margin-top: 4px; + */ +} + +@include media-breakpoint-up(lg) { + .navbar { + z-index: 1025; + } +} + +@include media-breakpoint-up(md) { + .navbar-brand { + font-size: $font-size-xl; + } + + .navbar-text { + margin-left: 1.25rem; + } +} + +.navbar-nav { + flex-direction: row; +} + +.nav-item { + margin-left: 0; +} + +@include media-breakpoint-up(md) { + .nav-item { + margin-left: 0.5rem; + } +} + +/* +@include media-breakpoint-down(sm) { + .nav-item:first-child { + margin-left: 0; + } +} +*/ + +@include media-breakpoint-down(md) { + .navbar .container { + padding-left: 1.5rem; + padding-right: 1.5rem; + } +} + +.break { + flex-basis: 100%; + height: 0; +} + +button#doks-languages { + margin-right: -0.5625rem; + margin-left: 0.75rem; +} + +button#doks-versions { + margin-right: -0.5625rem; + margin-left: 0; +} + +.offcanvas .nav-link { + color: $body-color; +} + +.doks-subnavbar { + background-color: rgba(255, 255, 255, 0.95); + border-bottom: 1px solid $gray-200; +} + +.doks-subnavbar .nav-link { + padding: 0.5rem 1.5rem 0.5rem 0; +} + +.doks-subnavbar .nav-link:first-child { + padding: 0.5rem 1.5rem 0.5rem 0; +} + +.offcanvas .nav-link:hover, +.offcanvas .nav-link:focus { + color: $link-color; +} + +.offcanvas .nav-link.active { + color: $link-color; +} + +/* +.navbar { + background-color: rgba(255, 255, 255, 0.95); + border-bottom: 1px solid $gray-200; + margin-top: 4px; +} +*/ + +.header-bar { + border-top: 4px solid; + border-image-source: linear-gradient(90deg, $primary, #8ed6fb 50%, #d32e9d); + border-image-slice: 1; +} + +.offcanvas .header-bar { + margin-bottom: -4px; +} + +.home .navbar { + border-bottom: 0; +} + +/* +.navbar-form { + position: relative; + margin-top: 0.25rem; +} +*/ + +@include media-breakpoint-up(md) { + .navbar-brand { + margin-right: 0.75rem !important; + } + + .main-nav .nav-item:first-child .nav-link, + .social-nav .nav-item:first-child .nav-link { + padding-left: 0; + } + + .main-nav .nav-item:last-child .nav-link, + .social-nav .nav-item:last-child .nav-link { + padding-right: 0; + } + + .doks-search { + max-width: 20rem; + margin-top: 0.125rem; + margin-bottom: 0.125rem; + } + + /* + .navbar-form { + margin-top: 0; + margin-left: 6rem; + margin-right: 1.5rem; + } + */ +} + +.form-control.is-search { + padding-right: 4rem; + border: 1px solid transparent; + background: $gray-100; +} + +.form-control.is-search:focus { + border: 1px solid $primary; +} + +.doks-search::after { + position: absolute; + top: 0.4625rem; + right: 0.5375rem; + display: flex; + align-items: center; + justify-content: center; + height: 1.5rem; + padding-right: 0.3125rem; + padding-left: 0.3125rem; + font-size: $font-size-base * 0.75; + color: $gray-700; + content: "Ctrl + /"; + border: 1px solid $gray-300; + border-radius: 0.25rem; +} + +/* +@include media-breakpoint-up(lg) { + .navbar-form { + margin-left: 15rem; + } +} + +@include media-breakpoint-up(xl) { + .navbar-form { + margin-left: 30rem; + } +} +*/ + +/* +.form-control.is-search { +*/ + +/* + padding-right: calc(1.5em + 0.75rem); + */ + +/* + padding-right: 2.5rem; + background: $gray-100; + border: 0; + */ + +/* + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 24 24' fill='none' stroke='%236c757d' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-search'%3E%3Ccircle cx='11' cy='11' r='8'%3E%3C/circle%3E%3Cline x1='21' y1='21' x2='16.65' y2='16.65'%3E%3C/line%3E%3C/svg%3E"); + background-repeat: no-repeat; + background-position: right calc(0.375em + 0.1875rem) center; + background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); + */ + +/* +} +*/ + +/* +.navbar-form::after { + position: absolute; + top: 0.4625rem; + right: 0.5375rem; + display: flex; + align-items: center; + justify-content: center; + height: 1.5rem; + padding-right: 0.4375rem; + padding-left: 0.4375rem; + font-size: $font-size-base * 0.75; + color: $gray-700; + content: "/"; + border: 1px solid $gray-300; + border-radius: 0.25rem; +} +*/ + +/*! purgecss start ignore */ +.algolia-autocomplete { + display: flex !important; +} + +.algolia-autocomplete .ds-dropdown-menu { + box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15) !important; +} + +@include media-breakpoint-down(sm) { + .algolia-autocomplete .ds-dropdown-menu { + max-width: 512px !important; + min-width: 312px !important; + width: auto !important; + } + + .algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--subcategory-column { + font-weight: normal; + } + + .algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--subcategory-column::after { + content: "/"; + margin-right: 0.25rem; + } +} + +.algolia-autocomplete .algolia-docsearch-suggestion--category-header { + color: $black; +} + +.algolia-autocomplete .algolia-docsearch-suggestion--title { + margin-bottom: 0; +} + +.algolia-autocomplete .algolia-docsearch-suggestion--highlight { + padding: 0 0.05em; +} + +.algolia-autocomplete .algolia-docsearch-footer { + margin-top: 1rem; + margin-right: 0.5rem; + margin-bottom: 0.5rem; +} + +/*! purgecss end ignore */ + +/* + * Source: https://medium.com/creative-technology-concepts-code/responsive-mobile-dropdown-navigation-using-css-only-7218e4498a99 +*/ + +/* Style the menu icon for the dropdown */ + +.navbar .menu-icon { + cursor: pointer; + + /* display: inline-block; */ + + /* float: right; */ + padding: 1.125rem 0.625rem; + margin: 0 0 0 -0.625rem; + + /* position: relative; */ + user-select: none; +} + +.navbar .menu-icon .navicon { + background: $navbar-light-color; + display: block; + height: 2px; + position: relative; + transition: background 0.2s ease-out; + width: 18px; +} + +.navbar .menu-icon .navicon::before, +.navbar .menu-icon .navicon::after { + background: $navbar-light-color; + content: ""; + display: block; + height: 100%; + position: absolute; + transition: all 0.2s ease-out; + width: 100%; +} + +.navbar .menu-icon .navicon::before { + top: 5px; +} + +.navbar .menu-icon .navicon::after { + top: -5px; +} + +/* Add the icon and menu animations when the checkbox is clicked */ + +.navbar .menu-btn { + display: none; +} + +.navbar .menu-btn:checked ~ .navbar-collapse { + display: block; + max-height: 100vh; +} + +.navbar .menu-btn:checked ~ .menu-icon .navicon { + background: transparent; +} + +.navbar .menu-btn:checked ~ .menu-icon .navicon::before { + transform: rotate(-45deg); +} + +.navbar .menu-btn:checked ~ .menu-icon .navicon::after { + transform: rotate(45deg); +} + +.navbar .menu-btn:checked ~ .menu-icon:not(.steps) .navicon::before, +.navbar .menu-btn:checked ~ .menu-icon:not(.steps) .navicon::after { + top: 0; +} + +.btn-menu { + margin-left: 1rem; +} + +.btn-menu, +.doks-sidebar-toggle { + padding-right: 0.25rem; + padding-left: 0.25rem; + margin-right: -0.5rem; +} + +.btn-menu:hover, +.btn-doks-light:hover, +.doks-sidebar-toggle:hover { + background: $pink-100; +} + +.btn-menu:focus, +.doks-sidebar-toggle:focus, +.doks-mode-toggle:focus { + outline: 0; +} + +.doks-sidebar-toggle .doks-collapse { + display: none; +} + +.doks-sidebar-toggle:not(.collapsed) .doks-expand { + display: none; +} + +.doks-sidebar-toggle:not(.collapsed) .doks-collapse { + display: inline-block; +} + +.navbar-light .navbar-brand, +.navbar-light .navbar-brand:hover, +.navbar-light .navbar-brand:active { + color: $body-color; +} + +.navbar-light .navbar-nav .active .nav-link { + color: $primary; +} + +.dropdown-divider { + border-top: 1px dashed $gray-200; +} + +.dropdown-item:hover { + background: $gray-100; +} + +.dropdown-item:active { + color: inherit; +} diff --git a/docs/assets/scss/layouts/_pages.scss b/docs/assets/scss/layouts/_pages.scss new file mode 100644 index 000000000..405ede950 --- /dev/null +++ b/docs/assets/scss/layouts/_pages.scss @@ -0,0 +1,64 @@ +.docs-content > h2[id]::before, +.docs-content > h3[id]::before, +.docs-content > h4[id]::before { + display: block; + height: 6rem; + margin-top: -6rem; + content: ""; +} + +.anchor { + visibility: hidden; +} + +h1:hover a, +h2:hover a, +h3:hover a, +h4:hover a { + visibility: visible; + text-decoration: none; +} + +.card-list { + margin-top: 2.25rem; +} + +.page-footer-meta { + margin-top: 3rem; +} + +.edit-page, +.last-modified { + font-size: $font-size-sm; + margin-top: 0.25rem; + margin-bottom: 0.25rem; +} + +@include media-breakpoint-up(md) { + .edit-page, + .last-modified { + font-size: $font-size-base; + margin-top: 0.75rem; + margin-bottom: 0.25rem; + } +} + +.edit-page svg, +.last-modified svg { + margin-right: 0.25rem; + margin-bottom: 0.25rem; +} + +p.meta { + margin-top: 0.5rem; + font-size: $font-size-base; +} + +.breadcrumb { + margin-top: 2.25rem; + font-size: $font-size-base; +} + +.page-link:hover { + text-decoration: none; +} diff --git a/docs/assets/scss/layouts/_posts.scss b/docs/assets/scss/layouts/_posts.scss new file mode 100644 index 000000000..da2766052 --- /dev/null +++ b/docs/assets/scss/layouts/_posts.scss @@ -0,0 +1,28 @@ +.home .card, +.contributors.list .card, +.blog.list .card { + margin-top: 2rem; + margin-bottom: 2rem; + transition: transform 0.3s; +} + +.home .card:hover, +.contributors.list .card:hover, +.blog.list .card:hover { + transform: scale(1.025); +} + +.home .card-body, +.contributors.list .card-body, +.blog.list .card-body { + padding: 0 2rem 1rem; +} + +.blog-header { + text-align: center; + margin-bottom: 2rem; +} + +.blog-footer { + text-align: center; +} diff --git a/docs/assets/scss/layouts/_sidebar.scss b/docs/assets/scss/layouts/_sidebar.scss new file mode 100644 index 000000000..88959bfe9 --- /dev/null +++ b/docs/assets/scss/layouts/_sidebar.scss @@ -0,0 +1,116 @@ +.docs-links, +.docs-toc { + scrollbar-width: thin; + scrollbar-color: $white $white; +} + +.docs-links::-webkit-scrollbar, +.docs-toc::-webkit-scrollbar { + width: 5px; +} + +.docs-links::-webkit-scrollbar-track, +.docs-toc::-webkit-scrollbar-track { + background: $white; +} + +.docs-links::-webkit-scrollbar-thumb, +.docs-toc::-webkit-scrollbar-thumb { + background: $white; +} + +.docs-links:hover, +.docs-toc:hover { + scrollbar-width: thin; + scrollbar-color: $gray-200 $white; +} + +.docs-links:hover::-webkit-scrollbar-thumb, +.docs-toc:hover::-webkit-scrollbar-thumb { + background: $gray-200; +} + +.docs-links::-webkit-scrollbar-thumb:hover, +.docs-toc::-webkit-scrollbar-thumb:hover { + background: $gray-200; +} + +.docs-links h3, +.page-links h3 { + text-transform: uppercase; + font-size: $font-size-base; + margin: 1.25rem 0 0.5rem; + padding: 1.5rem 0 0; +} + +@include media-breakpoint-up(lg) { + .docs-links h3, + .page-links h3 { + margin: 1.125rem 1.5rem 0.75rem 0; + padding: 1.375rem 0 0; + } +} + +.docs-links h3:not(:first-child) { + border-top: 1px solid $gray-200; +} + +a.docs-link { + color: $body-color; + display: block; + padding: 0.125rem 0; + font-size: $font-size-base; +} + +.page-links li { + margin-top: 0.375rem; + padding-top: 0.375rem; +} + +.page-links li ul li { + border-top: none; + padding-left: 1rem; + margin-top: 0.125rem; + padding-top: 0.125rem; +} + +.page-links li:not(:first-child) { + border-top: 1px dashed $gray-200; +} + +.page-links a { + color: $body-color; + display: block; + padding: 0.125rem 0; + font-size: $font-size-base * 0.9375; +} + +.docs-link:hover, +.docs-link.active, +.page-links a:hover { + text-decoration: none; + color: $link-color; +} + +.nav-link.active, +.dropdown-menu-main .dropdown-item.active, +.docs-link.active { + font-weight: 500; +} + +.docs-links h3.sidebar-link, +.page-links h3.sidebar-link { + text-transform: none; + font-size: $font-size-md; + font-weight: normal; +} + +.docs-links h3.sidebar-link a, +.page-links h3.sidebar-link a { + color: $body-color; +} + +.docs-links h3.sidebar-link a:hover, +.page-links h3.sidebar-link a:hover { + text-decoration: underline; +} diff --git a/docs/assets/scss/vendor/.gitkeep b/docs/assets/scss/vendor/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/docs/babel.config.js b/docs/babel.config.js new file mode 100644 index 000000000..ce9c9de02 --- /dev/null +++ b/docs/babel.config.js @@ -0,0 +1,17 @@ +module.exports = { + presets: [ + [ + '@babel/preset-env', + { + targets: { + browsers: [ + // Best practice: https://github.com/babel/babel/issues/7789 + '>=1%', + 'not ie 11', + 'not op_mini all' + ] + } + } + ] + ] +}; \ No newline at end of file diff --git a/docs/community/additional-resources.md b/docs/community/additional-resources.md deleted file mode 100644 index 6cccc3eef..000000000 --- a/docs/community/additional-resources.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -layout: default -title: Miscellaneous Additional Resources -parent: Community -nav_order: 3 ---- - -In this document you will find miscellaneous resources that could give you more -information on Authelia or help you set it up. - -# Articles - -[Setting Up Authelia With SWAG](https://blog.linuxserver.io/2020/08/26/setting-up-authelia/) -[Authelia Tutorial – Protect your Docker Traefik stack with Private MFA](https://www.smarthomebeginner.com/docker-authelia-tutorial/) - -# Youtube Videos - -[Authelia: Install Guide on Unraid + NGINX (Deep Dive)](https://www.youtube.com/watch?v=kw_pohbKE3Y) \ No newline at end of file diff --git a/docs/community/django-integration.md b/docs/community/django-integration.md deleted file mode 100644 index 0297c0746..000000000 --- a/docs/community/django-integration.md +++ /dev/null @@ -1,212 +0,0 @@ ---- -layout: default -title: Integrate Authelia with Django -parent: Community -nav_order: 6 ---- - -# Integrate Authelia with Django - -Django, the Python web framework, can be configured to delegate authentication to external services -using HTTP request headers. This is well documented on [Django documentation](https://docs.djangoproject.com/en/3.2/howto/auth-remote-user/) - -Therefore, it is possible to integrate Django with Authelia following the documentation about -[Proxy integration](https://www.authelia.com/docs/deployment/supported-proxies/#how-can-the-backend-be-aware-of-the-authenticated-users) -and adding a few lines of code on your Django application. - - -## Basic integration - -Django uses `REMOTE_USER` header by default. But WSGI servers transform the headers received from -proxy servers adding `HTTP_` as prefix. So we need to add a custom middleware in order to use `HTTP_REMOTE_USER`. - -This basic configuration enables authentication using Authelia. If the user does not exists on Django database, -it will be automatically created. - - -### Configuration - -```python -# file: settings.py - -MIDDLEWARE = [ - '...', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'your_app.auth.middleware.RemoteUserMiddleware', - # or 'your_app.auth.middleware.PersistentRemoteUserMiddleware', - '...', -] - -AUTHENTICATION_BACKENDS = [ - 'django.contrib.auth.backends.RemoteUserBackend', -] - -# Logout from authelia after logout on the Django application -LOGOUT_REDIRECT_URL = 'https://auth.your_domain.com/logout' - -``` - -### New authentication middleware - -```python -# new file: your_app/auth/middleware.py -from django.contrib.auth.middleware import RemoteUserMiddleware, PersistentRemoteUserMiddleware - - -class HttpRemoteUserMiddleware(RemoteUserMiddleware): - header = 'HTTP_REMOTE_USER' - - # uncomment the line below to disable authentication to users that not exists on Django database - # create_unknown_user = False - - -class PersistentHttpRemoteUserMiddleware(PersistentRemoteUserMiddleware): - """ - The RemoteUserMiddleware authentication middleware assumes that the HTTP request header - REMOTE_USER is present with all authenticated requests. - - With PersistentRemoteUserMiddleware, it is possible to receive this header only on a few - pages (as login page) and maintain the authenticated session until explicit - logout by the user. - """ - header = 'HTTP_REMOTE_USER' - -``` - -**Security Warning:** -The proxy server **must** set `Remote-User` header **every time** it hits the Django application. If you only -protect the login URL with Authelia and use the Persistent class, you have to set this header to `''` -on the other locations. - - -## Advanced integration - -While the basic integration only uses the HTTP header `Remote-User` set by Authelia, this advanced integration -uses also the HTTP headers `Remote-Name`, `Remote-Email` and `Remote-Groups`. - -In this example, we create a new authentication backend on Django that will synchronize user data with Authelia -backend, storing the name, the email and the groups of the user on the Django database. - -### Configuration - -```python -# file: settings.py - -MIDDLEWARE = [ - '...', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'your_app.auth.middleware.RemoteUserMiddleware', - # or 'your_app.auth.middleware.PersistentRemoteUserMiddleware', - '...', -] - -AUTHENTICATION_BACKENDS = [ - 'your_app.auth.backends.RemoteExtendedUserBackend', -] - -# Logout from authelia after logout on the Django application -LOGOUT_REDIRECT_URL = 'https://auth.your_domain.com/logout' - -``` - -### New authentication backend -```python -# new file: your_app/auth/backends.py -from django.conf import settings -from django.contrib.auth.models import Group -from django.contrib.auth.backends import RemoteUserBackend - - -class RemoteExtendedUserBackend(RemoteUserBackend): - """ - This backend can be used in conjunction with the ``RemoteUserMiddleware`` - to handle authentication outside Django and update local user with external information - (name, email and groups). - - Extends RemoteUserBackend (it creates the Django user if it does not exist, - as explained here: https://github.com/django/django/blob/main/django/contrib/auth/backends.py#L167), - updating the user with the information received from the remote headers. - - Django user is only added to groups that already exist on the database (no groups are created). - A settings variable can be used to exclude some groups when updating the user. - """ - - excluded_groups = set() - if hasattr(settings, 'REMOTE_AUTH_BACKEND_EXCLUDED_GROUPS'): - excluded_groups = set(settings.REMOTE_AUTH_BACKEND_EXCLUDED_GROUPS) - - # Warning: possible security breach if reverse proxy does not set - # these variables EVERY TIME it hits this Django application (and REMOTE_USER variable). - # See https://docs.djangoproject.com/en/4.0/howto/auth-remote-user/#configuration - header_name = 'HTTP_REMOTE_NAME' - header_groups = 'HTTP_REMOTE_GROUPS' - header_email = 'HTTP_REMOTE_EMAIL' - - def authenticate(self, request, remote_user): - user = super().authenticate(request, remote_user) - - # original authenticate calls configure_user only - # when user is created. We need to call this method every time - # the user is authenticated in order to update its data. - if user: - self.configure_user(request, user) - return user - - def configure_user(self, request, user): - """ - Complete the user from extra request.META information. - """ - if self.header_name in request.META: - user.last_name = request.META[self.header_name] - - if self.header_email in request.META: - user.email = request.META[self.header_email] - - if self.header_groups in request.META: - self.update_groups(user, request.META[self.header_groups]) - - if self.user_has_to_be_staff(user): - user.is_staff = True - - user.save() - return user - - def user_has_to_be_staff(self, user): - return True - - def update_groups(self, user, remote_groups): - """ - Synchronizes groups the user belongs to with remote information. - - Groups (existing django groups or remote groups) on excluded_groups are completely ignored. - No group will be created on the django database. - - Disclaimer: this method is strongly inspired by the LDAPBackend from django-auth-ldap. - """ - current_group_names = frozenset( - user.groups.values_list("name", flat=True).iterator() - ) - preserved_group_names = current_group_names.intersection(self.excluded_groups) - current_group_names = current_group_names - self.excluded_groups - - target_group_names = frozenset( - [x for x in map(self.clean_groupname, remote_groups.split(',')) if x is not None] - ) - target_group_names = target_group_names - self.excluded_groups - - if target_group_names != current_group_names: - target_group_names = target_group_names.union(preserved_group_names) - existing_groups = list( - Group.objects.filter(name__in=target_group_names).iterator() - ) - user.groups.set(existing_groups) - return - - def clean_groupname(self, groupname): - """ - Perform any cleaning on the "groupname" prior to using it. - Return the cleaned groupname. - """ - return groupname - -``` diff --git a/docs/community/example-of-authelia-lite-on-docker-swarm.md b/docs/community/example-of-authelia-lite-on-docker-swarm.md deleted file mode 100644 index 52cf543c2..000000000 --- a/docs/community/example-of-authelia-lite-on-docker-swarm.md +++ /dev/null @@ -1,181 +0,0 @@ ---- -layout: default -title: Example of authelia lite on docker swarm -parent: Community -nav_order: 4 ---- - -The overlay network for docker swarm can be initialized with: - -``` -$ docker swarm init -$ docker swarm init && docker network create --driver=overlay traefik-public -$ mkdir ./redis ./letsencrypt -``` - -The structure of the folder should be like this: - -``` -├── authelia/ -│   ├── configuration.yml -│   └── users_database.yml -├── redis/ -├── letsencrypt/ -│   └── acme.json -└── traefik-compose.yml -``` - -The following configuration allows you to deploy authelia to docker swarm with traefik 2.x. Please replace the **example.com** and **your@email.com** with your domain and email respectively. Then save it as **traefik-compose.yml**. - -``` -version: '3.3' - -services: - authelia: - image: authelia/authelia:4 - volumes: - - ./authelia:/config - networks: - - traefik-public - deploy: - labels: - - 'traefik.enable=true' - - 'traefik.http.routers.authelia.rule=Host(`auth.example.com`)' - - 'traefik.http.routers.authelia.entrypoints=web' - - "traefik.http.services.authelia.loadbalancer.server.port=9091" - # TLS - - "traefik.http.routers.authelias.rule=Host(`auth.example.com`)" - - "traefik.http.routers.authelias.entrypoints=websecure" - - "traefik.http.routers.authelias.tls.certresolver=letsencrypt" - # Redirect - - "traefik.http.routers.authelia.middlewares=https_redirect" - - "traefik.http.middlewares.https_redirect.redirectscheme.scheme=https" - # Authelia - - 'traefik.http.middlewares.authelia.forwardauth.address=http://authelia:9091/api/verify?rd=https://auth.example.com' - - 'traefik.http.middlewares.authelia.forwardauth.trustForwardHeader=true' - - 'traefik.http.middlewares.authelia.forwardauth.authResponseHeaders=Remote-User, Remote-Groups' - - "traefik.http.routers.authelia.service=authelia" - - redis: - image: redis:6-alpine - volumes: - - ./redis:/data - networks: - - traefik-public - - traefik: - # The official v2.0 Traefik docker image - image: traefik:v2.2 - deploy: - labels: - - 'traefik.enable=true' - - 'traefik.http.routers.api.rule=Host(`traefik.example.com`)' - - 'traefik.http.routers.api.entrypoints=web' - - 'traefik.http.routers.api.service=api@internal' - - 'traefik.http.services.traefik.loadbalancer.server.port=80' - # TLS - - "traefik.http.routers.apis.rule=Host(`traefik.example.com`)" - - "traefik.http.routers.apis.entrypoints=websecure" - - "traefik.http.routers.apis.tls.certresolver=letsencrypt" - # Redirect - - "traefik.http.routers.api.middlewares=https_redirect" - - "traefik.http.middlewares.https_redirect.redirectscheme.scheme=https" - # Authelia - - 'traefik.http.routers.apis.service=api@internal' - - 'traefik.http.routers.apis.middlewares=authelia@docker' - placement: - constraints: - - node.role == manager - command: - - "--api" - - "--providers.docker=true" - - "--providers.docker.swarmMode=true" - - "--providers.docker.exposedbydefault=false" - - "--entrypoints.web.address=:80" - - "--entryPoints.websecure.address=:443" - - "--certificatesresolvers.letsencrypt.acme.httpchallenge=true" - - "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web" - - "--certificatesresolvers.letsencrypt.acme.email=your@email.com" - - "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json" - ports: - # Listen on port 80, default for HTTP, necessary to redirect to HTTPS - - target: 80 - published: 80 - mode: host - # Listen on port 443, default for HTTPS - - target: 443 - published: 443 - mode: host - volumes: - # So that Traefik can listen to the Docker events - - /var/run/docker.sock:/var/run/docker.sock - - ./letsencrypt:/letsencrypt - networks: - - traefik-public - - secure: - image: containous/whoami - networks: - - traefik-public - deploy: - labels: - - 'traefik.enable=true' - - 'traefik.http.routers.secure.rule=Host(`secure.example.com`)' - - 'traefik.http.routers.secure.entrypoints=web' - - 'traefik.http.services.secure.loadbalancer.server.port=80' - # TLS - - "traefik.http.routers.secures.rule=Host(`secure.example.com`)" - - "traefik.http.routers.secures.entrypoints=websecure" - - "traefik.http.routers.secures.tls.certresolver=letsencrypt" - # Redirect - - "traefik.http.routers.secure.middlewares=https_redirect" - - "traefik.http.middlewares.https_redirect.redirectscheme.scheme=https" - # Authelia - - 'traefik.http.routers.secures.middlewares=authelia@docker' - - public: - image: containous/whoami - networks: - - traefik-public - deploy: - labels: - - 'traefik.enable=true' - - 'traefik.http.routers.public.rule=Host(`public.example.com`)' - - 'traefik.http.routers.public.entrypoints=web' - - 'traefik.http.services.public.loadbalancer.server.port=80' - # TLS - - "traefik.http.routers.publics.rule=Host(`public.example.com`)" - - "traefik.http.routers.publics.entrypoints=websecure" - - "traefik.http.routers.publics.tls.certresolver=letsencrypt" - # Redirect - - "traefik.http.routers.public.middlewares=https_redirect" - - "traefik.http.middlewares.https_redirect.redirectscheme.scheme=https" - # Authelia - - 'traefik.http.routers.publics.middlewares=authelia@docker' - -networks: - traefik-public: - external: true -``` - -Finally, the stack is ready to be deployed. - -``` -$ docker stack deploy -c traefik-compose.yml traefik -``` - -Full configuration files can be found here https://github.com/wuhanstudio/authelia-docker-swarm - -``` -$ docker swarm init && docker network create --driver=overlay traefik-public - -$ git clone https://github.com/wuhanstudio/authelia-docker-swarm && cd authelia-docker-swarm - -# Replace wuhanstudio.cc with your domain -$ find . -type f -name "*.yml" -exec sed -i'' -e 's/example.com/wuhanstudio.cc/g' {} + - -# Replace wuhanstudio@qq.com with your email -$ find . -type f -name "*.yml" -exec sed -i'' -e 's/your@email.com/wuhanstudio@qq.com/g' {} + - -$ docker stack deploy -c traefik-compose.yml traefik -``` diff --git a/docs/community/index.md b/docs/community/index.md deleted file mode 100644 index 923ec4597..000000000 --- a/docs/community/index.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -layout: default -title: Community -nav_order: 11 -has_children: true ---- - -# Community documentation - -This section is meant to advertise and organize documentation produced -by the community. This documentation is considered non-official and we -will not guarantee that this documentation is up-to-date. If you think -some of it should be considered official, please file an issue on GitHub. diff --git a/docs/community/oidc-integrations.md b/docs/community/oidc-integrations.md deleted file mode 100644 index d1cc2410a..000000000 --- a/docs/community/oidc-integrations.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -layout: default -title: Community-Tested OIDC Integrations -parent: Community -nav_order: 5 -has_children: true -has_toc: false ---- - -# OIDC Integrations - -**Note** This is community-based content for which the core-maintainers cannot guarantee correctness. The parameters may change over time. If a parameter does not work as documented, please submit a PR to update the list. - -## Currently Tested Applications - -| Application | Minimal Version | Notes | -|:----------------:|:------------------------------:|:-------------------------------------------------------------------------------------------------------------:| -| Bookstack | `21.10` | | -| Gitea | `1.14.6` | | -| GitLab | `13.0.0` | | -| Grafana | `8.0.5` | | -| Harbor | `1.10` | It works on >v2.1 also, but not sure if there is OIDC support on v2.0 | -| Hashicorp Vault | `1.8.1` | | -| Miniflux | `2.0.21` | | -| MinIO | `RELEASE.2021-11-09T03-21-45Z` | must set `MINIO_IDENTITY_OPENID_CLAIM_NAME: groups` in MinIO and set [MinIO policies](https://docs.min.io/minio/baremetal/security/minio-identity-management/policy-based-access-control.html#minio-policy) as groups in Authelia | -| Nextcloud | `22.1.0` | Tested using the `nextcloud-oidc-login` app - [Link](https://github.com/pulsejet/nextcloud-oidc-login) | -| Portainer CE | `2.6.1` | Settings to use username as ID: set `Scopes` to `openid` and `User Identifier` to `preferred_username` | -| Seafile | `9.0.4` | Requires `OAUTH_ATTRIBUTE_MAP` to contain the mapping of the `id` field even if not present in Authelia, e.g. `'id': (False, "unused")` (see [seahub#5162](https://github.com/haiwen/seahub/issues/5162)) | -| Verdaccio | `5` | Depends on this fork of verdaccio-github-oauth-ui: [Link](https://github.com/OnekO/verdaccio-github-oauth-ui) | -| Wekan | `5.41` | | - -## Known Callback URLs - -If you do not find the application in the list below, you will need to search for yourself - and maybe come back to open a PR to add your application to this list so others won't have to search for them. - -`` needs to be substituted with the full URL on which the application runs on. If GitLab, as an example, was reachable under `https://gitlab.example.com`, `` would be exactly the same. - -| Application | Version | Callback URL | Notes | -|:---------------:|:-------------------------------------:|:------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:| -| Bookstack | `21.10` | `/oidc/callback` | | -| Gitea | `1.14.6` | `/user/oauth2/authelia/callback` | `ROOT_URL` in `[server]` section of `app.ini` must be configured correctly. Typically it is `/`. The string `authelia` in the callback url is the `Authentication Name` of the configured Authentication Source in Gitea (Authentication Type: OAuth2, OAuth2 Provider: OpenID Connect). | -| GitLab | `14.0.1` | `/users/auth/openid_connect/callback` | | -| Harbor | `1.10` | `/-/oauth/callback` | | -| Hashicorp Vault | `14.0.1` | `/oidc/callback` and `/ui/vault/auth/oidc/oidc/callback` | | -| Miniflux | `2.0.21` | `/oauth2/oidc/callback` | Set via Miniflux `OAUTH2_REDIRECT_URL` [configuration parameter](https://miniflux.app/docs/configuration.html#oauth2-redirect-url). Example value follows this format | -| MinIO | `RELEASE.2021-07-12T02-44-53Z` | `/oauth_callback` | | -| Nextcloud | `22.1.0` + `nextcloud-oidc-login` app | `/apps/oidc_login/oidc` | | -| Portainer CE | `2.6.1` | `` | | -| Seafile | `9.0.4` | `/oauth/callback/` | Must exactly match `OAUTH_REDIRECT_URL` value as set in `seahub_settings.py` | -| Verdaccio | `5` | `/oidc/callback` | | -| Wekan | `5.41` | `/_oauth_oidc` | | diff --git a/docs/community/oidc-integrations/portainer.md b/docs/community/oidc-integrations/portainer.md deleted file mode 100644 index a54415c70..000000000 --- a/docs/community/oidc-integrations/portainer.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -layout: default -title: Portainer -parent: Community-Tested OIDC Integrations -grand_parent: Community -nav_order: 1 ---- - -# OIDC Integrations: Portainer - -{{ page.path }} - -**Note** these setting have been tested with authelia `v4.34.6` and Portainer (CE and EE) `2.12.2` - -## Authelia config - -The specific client config for portainer. - -```yaml -identity_providers: - oidc: - clients: - - id: portainer_client_id - description: Some description you want to shown on the Authelia consent page - secret: some secret string which should also be entered in the portainer config - public: false - authorization_policy: two_factor - audience: [] - scopes: - - openid - - profile - - groups - - email - redirect_uris: - - https://portainer.example.com - userinfo_signing_algorithm: none -``` - -## Portainer config - -To setup Authelia as SSO provider in portainer go to **Settings > Authentication** and select **Authentication method** OAuth and **Provider** Custom and make sure automatic user provision is turned so users get automatically created. - -**Note** make sure that Redirect URL matches exacty the redirect_uris in authelia config. Use `preferred_username` as the User identifier which makes sure the portianer user and authelia user have the same username. Scopes should be `openid profile groups email` **do not use commas** - -

- -

diff --git a/docs/community/oidc-integrations/proxmox.md b/docs/community/oidc-integrations/proxmox.md deleted file mode 100644 index 86183f34f..000000000 --- a/docs/community/oidc-integrations/proxmox.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -layout: default -title: Proxmox -parent: Community-Tested OIDC Integrations -grand_parent: Community -nav_order: 2 ---- - -# OIDC Integrations: Proxmox - -{{ page.path }} - -## Authelia config - -**Note** these setting have been tested with authelia `v4.33.2` and Proxmox `7.1-10` - -The specific client config for proxmox. - -```yaml -identity_providers: - oidc: - clients: - - id: some id you want to use on the client - description: Some description you want to shown on the Authelia consent page - secret: some secret string which should also be entered in the proxmox config - public: false - authorization_policy: two_factor - audience: [] - scopes: - - openid - redirect_uris: - - https://proxmox.example.com - userinfo_signing_algorithm: none -``` - -## Proxmox config - -Under Datacenter go to **Persmission > Realms** and add the an OpenID Connect Server - -

- -

\ No newline at end of file diff --git a/docs/community/two-factor-basic-auth.md b/docs/community/two-factor-basic-auth.md deleted file mode 100644 index 84dfb7acd..000000000 --- a/docs/community/two-factor-basic-auth.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -layout: default -title: 2FA through basic auth -parent: Community -nav_order: 1 ---- - -The following project allows you to use Authelia's one-time password (OTP) 2-factor authentication (2FA) through only -[basic auth](https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication) -and a custom credentials format described below. -This allows you to use 2FA on clients and scenarios -that demand basic auth, e.g. [webdav](https://en.wikipedia.org/wiki/WebDAV) network streaming. -More information: - -## [authelia-basic-2fa](https://github.com/ViRb3/authelia-basic-2fa) diff --git a/docs/community/using-remote-user-header-for-sso-with-jira.md b/docs/community/using-remote-user-header-for-sso-with-jira.md deleted file mode 100644 index fc42f4d36..000000000 --- a/docs/community/using-remote-user-header-for-sso-with-jira.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -layout: default -title: Using Remote-User header for SSO with Jira -parent: Community -nav_order: 2 ---- - -# Using Remote-User header for SSO with Jira - -You can make Jira auto-login to the user that is currently logged in to authelia. -I say "auto-login" as I couldn't find any plugin to actually be authentication -provider through HTTP headers only - LDAP though seems to have support. - -So this guide is targeted to authelia users that don't use any other authentication -backend. - -I'm using traefik with docker as an example, but any proxy that can forward -authelia `Remote-User` header is fine. - -First of all, users should exist on both Authelia and Jira, and have the same -username for this to work. Also you will have to -[pay for a plugin](https://marketplace.atlassian.com/apps/1212581/easy-sso-jira-kerberos-ntlm-saml?hosting=server&tab=overview). - -After both steps are done: - - Add `traefik.http.middlewares.authelia.forwardauth.authResponseHeaders=Remote-User` in the labels of authelia - - Add `traefik.http.routers.jira.middlewares=authelia@docker` in the labels of Jira (to actually enable Authelia for - the Jira instance) - - Install EasySSO in Jira - - Go to EasySSO preferences and add the "Remote-User" header under HTTP and tick the "Username" checkbox. - - Save - -## Other Systems - -While this guide is tailored for Jira, you can use a similar method with many other services like Jenkins and Grafana. diff --git a/docs/config/_default/config.toml b/docs/config/_default/config.toml new file mode 100644 index 000000000..5174a6a08 --- /dev/null +++ b/docs/config/_default/config.toml @@ -0,0 +1,89 @@ +baseurl = "https://www.authelia.com/" +canonifyURLs = false +disableAliases = true +disableHugoGeneratorInject = true +enableEmoji = true +enableGitInfo = true +enableRobotsTXT = true +languageCode = "en-US" +paginate = 7 +rssLimit = 10 +title = "Authelia" + +# Multilingual +defaultContentLanguage = "en" +disableLanguages = [] +# defaultContentLanguageInSubdir = true + +# add redirects/headers +[outputs] +home = ["HTML", "RSS", "REDIRECTS", "HEADERS"] +section = ["HTML", "RSS", "SITEMAP"] + +# remove .{ext} from text/netlify +[mediaTypes."text/netlify"] +suffixes = [""] +delimiter = "" + +# add output format for netlify _redirects +[outputFormats.REDIRECTS] +mediaType = "text/netlify" +baseName = "_redirects" +isPlainText = true +notAlternative = true + +# add output format for netlify _headers +[outputFormats.HEADERS] +mediaType = "text/netlify" +baseName = "_headers" +isPlainText = true +notAlternative = true + +# add output format for section sitemap.xml +[outputFormats.SITEMAP] +mediaType = "application/xml" +baseName = "sitemap" +isHTML = false +isPlainText = true +noUgly = true +rel = "sitemap" + +[caches] + [caches.getjson] + dir = ":cacheDir/:project" + maxAge = "10s" + +[sitemap] + changefreq = "weekly" + filename = "sitemap.xml" + priority = 0.5 + +[taxonomies] + contributor = "contributors" + +[permalinks] + blog = "/blog/:title/" + +[minify.tdewolff.html] + keepWhitespace = false + +[module] + [module.hugoVersion] + extended = true + min = "0.80.0" + max = "" + [[module.mounts]] + source = "assets" + target = "assets" + [[module.mounts]] + source = "static" + target = "static" + [[module.mounts]] + source = "node_modules/flexsearch" + target = "assets/js/vendor/flexsearch" + [[module.mounts]] + source = "node_modules/katex" + target = "assets/js/vendor/katex" + [[module.mounts]] + source = "node_modules/mermaid" + target = "assets/js/vendor/mermaid" diff --git a/docs/config/_default/languages.toml b/docs/config/_default/languages.toml new file mode 100644 index 000000000..6ee6333fa --- /dev/null +++ b/docs/config/_default/languages.toml @@ -0,0 +1,6 @@ +[en] + languageName = "English" + contentDir = "content/en" + weight = 10 + [en.params] + languageISO = "EN" diff --git a/docs/config/_default/markup.toml b/docs/config/_default/markup.toml new file mode 100644 index 000000000..7960409d5 --- /dev/null +++ b/docs/config/_default/markup.toml @@ -0,0 +1,29 @@ +defaultMarkdownHandler = "goldmark" + +[goldmark] + [goldmark.extensions] + linkify = true + [goldmark.parser] + autoHeadingID = true + autoHeadingIDType = "github" + [goldmark.parser.attribute] + block = true + title = true + [goldmark.renderer] + unsafe = true + +[highlight] + codeFences = false + guessSyntax = false + hl_Lines = "" + lineNoStart = 1 + lineNos = false + lineNumbersInTable = true + noClasses = false + style = "dracula" + tabWidth = 4 + +[tableOfContents] + endLevel = 4 + ordered = false + startLevel = 2 diff --git a/docs/config/_default/menus/menus.en.toml b/docs/config/_default/menus/menus.en.toml new file mode 100644 index 000000000..2cb6e6245 --- /dev/null +++ b/docs/config/_default/menus/menus.en.toml @@ -0,0 +1,68 @@ +[[main]] + name = "Overview" + identifier = "overview" + url = "/overview/prologue/introduction/" + weight = 10 + +[[main]] + name = "Configuration" + identifier = "configuration" + url = "/configuration/prologue/introduction/" + weight = 20 + +[[main]] + name = "Integration" + identifier = "integration" + url = "/integration/prologue/introduction/" + weight = 30 + +[[main]] + name = "Contributing" + identifier = "contributing" + url = "/contributing/prologue/introduction" + weight = 40 + +[[main]] + name = "Blog" + identifier = "blog" + url = "/blog/" + weight = 50 + +[[main]] + name = "Roadmap" + identifier = "roadmap" + url = "/roadmap/prologue/introduction/" + weight = 80 + +[[main]] + name = "Reference" + identifier = "reference" + url = "/reference/prologue/introduction/" + weight = 90 + +[[social]] + name = "GitHub" + pre = "" + url = "https://github.com/authelia/authelia" + post = "v0.1.0" + weight = 10 + +[[footer]] + name = "Privacy" + url = "/information/privacy-policy" + weight = 10 + +[[footer]] + name = "Code of Conduct" + url = "/information/code-of-conduct" + weight = 20 + +[[footer]] + name = "Security" + url = "/information/security" + weight = 30 + +[[footer]] + name = "Contact" + url = "/information/contact" + weight = 40 diff --git a/docs/config/_default/params.toml b/docs/config/_default/params.toml new file mode 100644 index 000000000..10cd7ed9c --- /dev/null +++ b/docs/config/_default/params.toml @@ -0,0 +1,95 @@ +# Meta Data for SEO + +## Homepage +title = "Authelia" +titleSeparator = "-" +titleAddition = "The Single Sign-On Multi-Factor portal for web apps" +description = "Authelia is an open-source authentication and authorization server and portal fulfilling the identity and access management (IAM) role of information security in providing multi-factor authentication and single sign-on (SSO) for your applications via a web portal. It acts as a companion for common reverse proxies." + +## Documentation +# docsVersion = "0.3" + +## Open Graph +images = ["authelia.png"] +ogLocale = "en_US" +domainTLD = "authelia.com" +titleHome = "Authelia" + +## Twitter Cards +# twitterSite = "" +# twitterCreator = "" + +## JSON-LD +schemaType = "Organization" +schemaName = "Authelia" +schemaAuthor = "Authelia" +# schemaAuthorTwitter = "" +# schemaAuthorLinkedIn = "" +schemaAuthorGitHub = "https://github.com/authelia" +schemaLocale = "en-US" +schemaLogo = "logo-doks.png" +schemaLogoWidth = 512 +schemaLogoHeight = 512 +schemaImage = "doks.png" +schemaImageWidth = 1280 +schemaImageHeight = 640 +# schemaTwitter = "" +# schemaLinkedIn = "" +schemaGitHub = "https://github.com/authelia/authelia" +schemaSection = "blog" + +## Sitelinks Search Box +siteLinksSearchBox = false + +## Chrome Browser +themeColor = "#fff" + +# Images +quality = 85 +bgColor = "#fff" +landscapePhotoWidths = [900, 800, 700, 600, 500] +portraitPhotoWidths = [800, 700, 600, 500] +lqipWidth = "20x" +smallLimit = "300" + +# Footer +footer = "Powered by Netlify, Hugo, and Doks" + +# Feed +copyRight = "Copyright © 2016-%s Authelia" + +# Alert +alert = true +alertDismissable = true +alertText = "Help us improve Authelia by taking this 10 second survey." + +# Edit Page +repoHost = "GitHub" +docsRepo = "https://github.com/authelia/authelia" +docsRepoBranch = "master" +docsRepoSubPath = "docs" +editPage = true +lastMod = true + +[options] + lazySizes = true + clipBoard = true + instantPage = true + flexSearch = true + darkMode = true + bootStrapJs = true + breadCrumb = true + highLight = true + kaTex = false + multilingualMode = false + docsVersioning = false + fullWidth = false + +[menu] + [menu.section] + auto = true + collapsibleSidebar = true + +[Sections] + Search = ["overview", "configuration", "integration", "contributing", "reference"] + Searchable = ["blog"] diff --git a/docs/config/next/config.toml b/docs/config/next/config.toml new file mode 100644 index 000000000..9c5e90da5 --- /dev/null +++ b/docs/config/next/config.toml @@ -0,0 +1 @@ +canonifyURLs = false diff --git a/docs/config/postcss.config.js b/docs/config/postcss.config.js new file mode 100644 index 000000000..f9d1a18ab --- /dev/null +++ b/docs/config/postcss.config.js @@ -0,0 +1,39 @@ +const autoprefixer = require('autoprefixer'); +const purgecss = require('@fullhuman/postcss-purgecss'); +const whitelister = require('purgecss-whitelister'); + +module.exports = { + plugins: [ + autoprefixer(), + purgecss({ + content: [ + './layouts/**/*.html', + './content/**/*.md', + ], + safelist: [ + 'lazyloaded', + 'table', + 'thead', + 'tbody', + 'tr', + 'th', + 'td', + 'h5', + 'alert-link', + 'container-xxl', + 'container-fluid', + ...whitelister([ + './assets/scss/components/_alerts.scss', + './assets/scss/components/_buttons.scss', + './assets/scss/components/_code.scss', + './assets/scss/components/_diagrams.scss', + './assets/scss/components/_syntax.scss', + './assets/scss/components/_search.scss', + './assets/scss/common/_dark.scss', + './node_modules/bootstrap/scss/_dropdown.scss', + './node_modules/katex/dist/katex.css', + ]), + ], + }), + ], +} diff --git a/docs/config/production/config.toml b/docs/config/production/config.toml new file mode 100644 index 000000000..9c5e90da5 --- /dev/null +++ b/docs/config/production/config.toml @@ -0,0 +1 @@ +canonifyURLs = false diff --git a/docs/config/staging/config.toml b/docs/config/staging/config.toml new file mode 100644 index 000000000..31a41916f --- /dev/null +++ b/docs/config/staging/config.toml @@ -0,0 +1,2 @@ +canonifyURLs = false +baseurl = "https://authelia-staging.netlify.app/" diff --git a/docs/configuration/authentication/file.md b/docs/configuration/authentication/file.md deleted file mode 100644 index 3a8565422..000000000 --- a/docs/configuration/authentication/file.md +++ /dev/null @@ -1,247 +0,0 @@ ---- -layout: default -title: File -parent: Authentication Backends -grand_parent: Configuration -nav_order: 1 ---- - -# File - -**Authelia** supports a file as a users database. - - -## Configuration - -Configuring Authelia to use a file is done by specifying the path to the -file in the configuration file. - -```yaml -authentication_backend: - disable_reset_password: false - file: - path: /config/users.yml - password: - algorithm: argon2id - iterations: 3 - salt_length: 16 - key_length: 32 - parallelism: 4 - memory: 64 -``` - -## Format - -The format of the users file is as follows. - -```yaml -users: - john: - displayname: "John Doe" - password: "$argon2id$v=19$m=65536,t=3,p=2$BpLnfgDsc2WD8F2q$o/vzA4myCqZZ36bUGsDY//8mKUYNZZaR0t4MFFSs+iM" - email: john.doe@authelia.com - groups: - - admins - - dev - harry: - displayname: "Harry Potter" - password: "$argon2id$v=19$m=65536,t=3,p=2$BpLnfgDsc2WD8F2q$o/vzA4myCqZZ36bUGsDY//8mKUYNZZaR0t4MFFSs+iM" - email: harry.potter@authelia.com - groups: [] - bob: - displayname: "Bob Dylan" - password: "$argon2id$v=19$m=65536,t=3,p=2$BpLnfgDsc2WD8F2q$o/vzA4myCqZZ36bUGsDY//8mKUYNZZaR0t4MFFSs+iM" - email: bob.dylan@authelia.com - groups: - - dev - james: - displayname: "James Dean" - password: "$argon2id$v=19$m=65536,t=3,p=2$BpLnfgDsc2WD8F2q$o/vzA4myCqZZ36bUGsDY//8mKUYNZZaR0t4MFFSs+iM" - email: james.dean@authelia.com -``` - -This file should be set with read/write permissions as it could be updated by users -resetting their passwords. - - -## Options - -### path -
-type: string (path) -{: .label .label-config .label-purple } -required: yes -{: .label .label-config .label-red } -
- - -### password - -#### algorithm -
-type: string -{: .label .label-config .label-purple } -default: argon2id -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -Controls the hashing algorithm used for hashing new passwords. Value must be one of `argon2id` or `sha512`. - - -#### iterations -
-type: integer -{: .label .label-config .label-purple } -required: no -{: .label .label-config .label-green } -
- -Controls the number of hashing iterations done by the other hashing settings. - -When using `argon2id` the minimum is 3, which is also the recommended and default value. - -When using `sha512` the minimum is 1000, and 50000 is the recommended and default value. - - -#### salt_length -
-type: integer -{: .label .label-config .label-purple } -default: 16 -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -Controls the length of the random salt added to each password before hashing. It's recommended this value is set to 16, -and there is no documented reason why you'd set it to anything other than this, however the minimum is 8. - - -#### parallelism -
-type: integer -{: .label .label-config .label-purple } -default: 4 -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -This setting is specific to `argon2id` and unused with `sha512`. Sets the number of threads used when hashing passwords, -which affects the effective cost of hashing. - - -#### memory -
-type: integer -{: .label .label-config .label-purple } -default: 64 -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -This setting is specific to `argon2id` and unused with `sha512`. Sets the amount of memory allocated to a single -password hashing action. This memory is released by go after the hashing process completes, however the operating system -may not reclaim it until it needs the memory which may make Authelia appear to be using more memory than it technically -is. - -## Passwords - -The file contains hashed passwords instead of plain text passwords for security reasons. - -You can use Authelia binary or docker image to generate the hash of any password. The -hash-password command has many tunable options, you can view them with the -`authelia hash-password --help` command. For example if you wanted to improve the entropy -you could generate a 16 byte salt and provide it with the `--salt` flag. -Example: `authelia hash-password --salt abcdefghijklhijl -- 'yourpassword'`. For argon2id the salt must -always be valid for base64 decoding (characters a through z, A through Z, 0 through 9, and +/). - -Passwords passed to `hash-password` should be single quoted if using special characters to prevent parameter substitution. -For instance to generate a hash with the docker image just run: - - $ docker run authelia/authelia:latest authelia hash-password -- 'yourpassword' - Password hash: $argon2id$v=19$m=65536$3oc26byQuSkQqksq$zM1QiTvVPrMfV6BVLs2t4gM+af5IN7euO0VB6+Q8ZFs - -You may also use the `--config` flag to point to your existing configuration. When used, the values defined in the config will be used instead. - -Full CLI Help Documentation: - -``` -Hash a password to be used in file-based users database. Default algorithm is argon2id. - -Usage: - authelia hash-password [flags] -- - -Flags: - -c, --config strings Configuration files - -h, --help help for hash-password - -i, --iterations int set the number of hashing iterations (default 3) - -k, --key-length int [argon2id] set the key length param (default 32) - -m, --memory int [argon2id] set the amount of memory param (in MB) (default 64) - -p, --parallelism int [argon2id] set the parallelism param (default 4) - -s, --salt string set the salt string - -l, --salt-length int set the auto-generated salt length (default 16) - -z, --sha512 use sha512 as the algorithm (changes iterations to 50000, change with -i) -``` - -### Password hash algorithm - -The default hash algorithm is Argon2id version 19 with a salt. Argon2id is currently considered -the best hashing algorithm, and in 2015 won the -[Password Hashing Competition](https://en.wikipedia.org/wiki/Password_Hashing_Competition). -It benefits from customizable parameters allowing the cost of computing a hash to scale -into the future which makes it harder to brute-force. Argon2id was implemented due to community -feedback as you can see in this closed [issue](https://github.com/authelia/authelia/issues/577). - -For backwards compatibility and user choice support for the SHA512 algorithm is still available. -While it's a reasonable hashing function given high enough iterations, as hardware improves it -has a higher chance of being brute-forced. - -Hashes are identifiable as argon2id or SHA512 by their prefix of either `$argon2id$` and `$6$` -respectively, as described in this [wiki page](https://en.wikipedia.org/wiki/Crypt_(C)). - -**Important Note:** When using argon2id Authelia will appear to remain using the memory allocated -to creating the hash. This is due to how [Go](https://golang.org/) allocates memory to the heap when -generating an argon2id hash. Go periodically garbage collects the heap, however this doesn't remove -the memory allocation, it keeps it allocated even though it's technically unused. Under memory -pressure the unused allocated memory will be reclaimed by the operating system, you can test -this on linux with: - - $ stress-ng --vm-bytes $(awk '/MemFree/{printf "%d\n", $2 * 0.9;}' < /proc/meminfo)k --vm-keep -m 1 - -If this is not desirable we recommend investigating the following options in order of most to least secure: -1. using the [LDAP authentication provider](./ldap.md) -2. adjusting the [memory](#memory) parameter -3. changing the [algorithm](#algorithm) - -### Password hash algorithm tuning - -All algorithm tuning for Argon2id is supported. The only configuration variables that affect -SHA512 are iterations and salt length. The configuration variables are unique to the file -authentication provider, thus they all exist in a key under the file authentication configuration -key called `password`. We have set what are considered as sane and recommended defaults -to cater for a reasonable system, if you're unsure about which settings to tune, please see the -parameters below, or for a more in depth understanding see the referenced documentation in -[Argon2 links](./file.md#argon2-links). - -#### Recommended Parameters: Argon2id - -This table is adapted from [RFC9106 Parameter Choice]: - -| Situation | Iterations (t) | Parallelism (p) | Memory (m) | Salt Size | Key Size | -|:-----------:|:--------------:|:---------------:|:----------:|:---------:|:--------:| -| Low Memory | 3 | 4 | 64 | 16 | 32 | -| Recommended | 1 | 4 | 2048 | 16 | 32 | - -## Argon2 Links - -- [Go Documentation](https://godoc.org/golang.org/x/crypto/argon2) -- Argon2 Specification [RFC9106] -- [OWASP Password Storage Cheatsheet] - -[RFC9106]: https://www.rfc-editor.org/rfc/rfc9106.html -[RFC9106 Parameter Choice]: https://www.rfc-editor.org/rfc/rfc9106.html#section-4 -[OWASP Password Storage Cheatsheet]: https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html diff --git a/docs/configuration/authentication/index.md b/docs/configuration/authentication/index.md deleted file mode 100644 index be1204443..000000000 --- a/docs/configuration/authentication/index.md +++ /dev/null @@ -1,62 +0,0 @@ ---- -layout: default -title: Authentication Backends -parent: Configuration -nav_order: 2 -has_children: true ---- - -# Authentication Backends - -There are two ways to store the users along with their password: - -* LDAP: users are stored in remote servers like OpenLDAP, OpenAM or Microsoft Active Directory. -* File: users are stored in YAML file with a hashed version of their password. - -## Configuration - -```yaml -authentication_backend: - disable_reset_password: false - password_reset: - custom_url: "" - file: {} - ldap: {} -``` - -## Options - -### disable_reset_password -
-type: boolean -{: .label .label-config .label-purple } -default: false -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -This setting controls if users can reset their password from the web frontend or not. - -### password_reset - -#### custom_url -
-type: string -{: .label .label-config .label-purple } -default: "" -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -The custom password reset URL. This replaces the inbuilt password reset functionality and disables the endpoints if -this is configured to anything other than nothing or an empty string. - -### file - -The [file](file.md) authentication provider. - -### ldap - -The [LDAP](ldap.md) authentication provider. diff --git a/docs/configuration/authentication/ldap.md b/docs/configuration/authentication/ldap.md deleted file mode 100644 index 70e2ef522..000000000 --- a/docs/configuration/authentication/ldap.md +++ /dev/null @@ -1,336 +0,0 @@ ---- -layout: default -title: LDAP -parent: Authentication Backends -grand_parent: Configuration -nav_order: 2 ---- - -# LDAP -**Authelia** supports using a LDAP server as the users database. - -## Configuration -```yaml -authentication_backend: - disable_reset_password: false - refresh_interval: 5m - ldap: - implementation: custom - url: ldap://127.0.0.1 - timeout: 5s - start_tls: false - tls: - server_name: ldap.example.com - skip_verify: false - minimum_version: TLS1.2 - base_dn: DC=example,DC=com - username_attribute: uid - additional_users_dn: ou=users - users_filter: (&({username_attribute}={input})(objectClass=person)) - additional_groups_dn: ou=groups - groups_filter: (&(member={dn})(objectClass=groupOfNames)) - group_name_attribute: cn - mail_attribute: mail - display_name_attribute: displayName - permit_referrals: false - user: CN=admin,DC=example,DC=com - password: password -``` - -## Options - -### implementation -
-type: string -{: .label .label-config .label-purple } -default: custom -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -Configures the LDAP implementation used by Authelia. - -See the [Implementation Guide](#implementation-guide) for information. - -### url -
-type: string -{: .label .label-config .label-purple } -required: yes -{: .label .label-config .label-red } -
- -The LDAP URL which consists of a scheme, address, and port. Format is `://
:` or -`://
` where scheme is either `ldap` or `ldaps`. - -If utilising an IPv6 literal address it must be enclosed by square brackets: - -```yaml -url: ldap://[fd00:1111:2222:3333::1] -``` - -### timeout -
-type: duration -{: .label .label-config .label-purple } -default: 5s -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -The timeout for dialing an LDAP connection. - -### start_tls -
-type: boolean -{: .label .label-config .label-purple } -default: false -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -Enables use of the LDAP StartTLS process which is not commonly used. You should only configure this if you know you need -it. The initial connection will be over plain text, and Authelia will try to upgrade it with the LDAP server. LDAPS -URL's are slightly more secure. - -### tls -Controls the TLS connection validation process. You can see how to configure the tls -section [here](../index.md#tls-configuration). - -### base_dn -
-type: string -{: .label .label-config .label-purple } -required: yes -{: .label .label-config .label-red } -
- -Sets the base distinguished name container for all LDAP queries. If your LDAP domain is example.com this is usually -`dc=example,dc=com`, however you can fine tune this to be more specific for example to only include objects inside the -authelia OU: `ou=authelia,dc=example,dc=com`. This is prefixed with the [additional_users_dn](#additional_users_dn) for -user searches and [additional_groups_dn](#additional_groups_dn) for groups searches. - -### username_attribute -
-type: string -{: .label .label-config .label-purple } -required: yes -{: .label .label-config .label-red } -
- -_**Note:** While this option is required, an [implementation](#implementation) may set a default value implicitly -negating this requirement. Refer to the [attribute defaults](#attribute-defaults) for more information._ - -The LDAP attribute that maps to the username in Authelia. - -### additional_users_dn -
-type: string -{: .label .label-config .label-purple } -required: no -{: .label .label-config .label-green } -
- -Additional LDAP path to append to the [base_dn](#base_dn) when searching for users. Useful if you want to restrict -exactly which OU to get users from for either security or performance reasons. For example setting it to -`ou=users,ou=people` with a base_dn set to `dc=example,dc=com` will mean user searches will occur in -`ou=users,ou=people,dc=example,dc=com`. The default value is dependent on the [implementation](#implementation), refer -to the [attribute defaults](#attribute-defaults) for more information. - -### users_filter -
-type: string -{: .label .label-config .label-purple } -required: yes -{: .label .label-config .label-red } -
- -_**Note:** While this option is required, an [implementation](#implementation) may set a default value implicitly -negating this requirement. Refer to the [attribute defaults](#attribute-defaults) for more information._ - -The LDAP filter to narrow down which users are valid. This is important to set correctly as to exclude disabled users. - -### group_name_attribute -
-type: string -{: .label .label-config .label-purple } -required: yes -{: .label .label-config .label-red } -
- -_**Note:** While this option is required, an [implementation](#implementation) may set a default value implicitly -negating this requirement. Refer to the [attribute defaults](#attribute-defaults) for more information._ - -The LDAP attribute that is used by Authelia to determine the group name. - -### additional_groups_dn -
-type: string -{: .label .label-config .label-purple } -required: no -{: .label .label-config .label-green } -
- -Similar to [additional_users_dn](#additional_users_dn) but it applies to group searches. - -### groups_filter -
-type: string -{: .label .label-config .label-purple } -required: yes -{: .label .label-config .label-red } -
- -_**Note:** While this option is required, an [implementation](#implementation) may set a default value implicitly -negating this requirement. Refer to the [attribute defaults](#attribute-defaults) for more information._ - -Similar to [users_filter](#users_filter) but it applies to group searches. In order to include groups the member is not -a direct member of, but is a member of another group that is a member of those (i.e. recursive groups), you may try -using the following filter which is currently only tested against Microsoft Active Directory: - -`(&(member:1.2.840.113556.1.4.1941:={dn})(objectClass=group)(objectCategory=group))` - -### mail_attribute -
-type: string -{: .label .label-config .label-purple } -required: yes -{: .label .label-config .label-red } -
- -_**Note:** While this option is required, an [implementation](#implementation) may set a default value implicitly -negating this requirement. Refer to the [attribute defaults](#attribute-defaults) for more information._ - -The attribute to retrieve which contains the users email addresses. This is important for the device registration and -password reset processes. - -The user must have an email address in order for Authelia to perform identity verification when a user attempts to reset -their password or register a second factor device. - -### display_name_attribute -
-type: string -{: .label .label-config .label-purple } -required: yes -{: .label .label-config .label-red } -
- -_**Note:** While this option is required, an [implementation](#implementation) may set a default value implicitly -negating this requirement. Refer to the [attribute defaults](#attribute-defaults) for more information._ - -The attribute to retrieve which is shown on the Web UI to the user when they log in. - -### permit_referrals -
-type: boolean -{: .label .label-config .label-purple } -default: false -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-red } -
- -Permits following referrals. This is useful if you have read-only servers in your architecture and thus require -referrals to be followed when performing write operations. This is only implemented for password modifications, if you -need this for searches please open a GitHub issue or contact us. - -### user -The distinguished name of the user paired with the password to bind with for lookup and password change operations. - -### password -The password of the user paired with the user to bind with for lookup and password change operations. -Can also be defined using a [secret](../secrets.md) which is the recommended for containerized deployments. - -## Implementation Guide -There are currently two implementations, `custom` and `activedirectory`. The `activedirectory` implementation -must be used if you wish to allow users to change or reset their password as Active Directory -uses a custom attribute for this, and an input format other implementations do not use. The long term -intention of this is to have logical defaults for various RFC implementations of LDAP. - -### Filter replacements -Various replacements occur in the user and groups filter. The replacements either occur at startup or upon an LDAP -search. - -#### Users filter replacements - -| Placeholder | Phase | Replacement | -|:------------------------:|:-------:|:-------------------------------------:| -| {username_attribute} | startup | The configured username attribute | -| {mail_attribute} | startup | The configured mail attribute | -| {display_name_attribute} | startup | The configured display name attribute | -| {input} | search | The input into the username field | - -#### Groups filter replacements - -| Placeholder | Phase | Replacement | -|:-----------:|:------:|:-------------------------------------------------------------------------:| -| {input} | search | The input into the username field | -| {username} | search | The username from the profile lookup obtained from the username attribute | -| {dn} | search | The distinguished name from the profile lookup | - -### Defaults -The below tables describes the current attribute defaults for each implementation. - -#### Attribute defaults -This table describes the attribute defaults for each implementation. i.e. the username_attribute is -described by the Username column. - -| Implementation | Username | Display Name | Mail | Group Name | -|:---------------:|:--------------:|:------------:|:----:|:----------:| -| custom | n/a | displayName | mail | cn | -| activedirectory | sAMAccountName | displayName | mail | cn | - -#### Filter defaults -The filters are probably the most important part to get correct when setting up LDAP. -You want to exclude disabled accounts. The active directory example has two attribute -filters that accomplish this as an example (more examples would be appreciated). The -userAccountControl filter checks that the account is not disabled and the pwdLastSet -makes sure that value is not 0 which means the password requires changing at the next login. - -| Implementation | Users Filter | Groups Filter | -|:---------------:|:---------------------------------------------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------:| -| custom | n/a | n/a | -| activedirectory | (&(|({username_attribute}={input})({mail_attribute}={input}))(sAMAccountType=805306368)(!(userAccountControl:1.2.840.113556.1.4.803:=2))(!(pwdLastSet=0))) | (&(member={dn})(objectClass=group)(objectCategory=group)) | - -_**Note:**_ The Active Directory filter `(sAMAccountType=805306368)` is exactly the same as -`(&(objectCategory=person)(objectClass=user))` except that the former is more performant, you can read more about this -and other Active Directory filters on the -[TechNet wiki](https://social.technet.microsoft.com/wiki/contents/articles/5392.active-directory-ldap-syntax-filters.aspx). - -## Refresh Interval -This setting takes a [duration notation](../index.md#duration-notation-format) that sets the max frequency -for how often Authelia contacts the backend to verify the user still exists and that the groups stored -in the session are up to date. This allows us to destroy sessions when the user no longer matches the -user_filter, or deny access to resources as they are removed from groups. - -In addition to the duration notation, you may provide the value `always` or `disable`. Setting to `always` -is the same as setting it to 0 which will refresh on every request, `disable` turns the feature off, which is -not recommended. This completely prevents Authelia from refreshing this information, and it would only be -refreshed when the user session gets destroyed by other means like inactivity, session expiration or logging -out and in. - -This value can be any value including 0, setting it to 0 would automatically refresh the session on -every single request. This means Authelia will have to contact the LDAP backend every time an element -on a page loads which could be substantially costly. It's a trade-off between load and security that -you should adapt according to your own security policy. - -## Important notes -Users must be uniquely identified by an attribute, this attribute must obviously contain a single value and -be guaranteed by the administrator to be unique. If multiple users have the same value, Authelia will simply -fail authenticating the user and display an error message in the logs. - -In order to avoid such problems, we highly recommended you follow https://www.ietf.org/rfc/rfc2307.txt by using -`sAMAccountName` for Active Directory and `uid` for other implementations as the attribute holding the -unique identifier for your users. - -As of versions > `4.24.0` the `users_filter` must include the `username_attribute` placeholder, not including this will -result in Authelia throwing an error. -In versions <= `4.24.0` not including the `username_attribute` placeholder will cause issues with the session refresh -and will result in session resets when the refresh interval has expired, default of 5 minutes. - -[LDAP GeneralizedTime]: https://ldapwiki.com/wiki/GeneralizedTime -[username attribute]: #username_attribute -[TechNet wiki]: https://social.technet.microsoft.com/wiki/contents/articles/5392.active-directory-ldap-syntax-filters.aspx diff --git a/docs/configuration/duo-push-notifications.md b/docs/configuration/duo-push-notifications.md deleted file mode 100644 index 26af6e27c..000000000 --- a/docs/configuration/duo-push-notifications.md +++ /dev/null @@ -1,97 +0,0 @@ ---- -layout: default -title: Duo Push Notifications -parent: Configuration -nav_order: 3 ---- - -# Duo Push Notifications - -Authelia supports mobile push notifications relying on [Duo]. - -Follow the instructions in the dedicated [documentation](../features/2fa/push-notifications.md) -to know how to set up push notifications in Authelia. - -**Note:** The configuration options in the following sections are noted as required. They are however only required when -you have this section defined. i.e. if you don't wish to use the [Duo] push notifications you can just not define this -section of the configuration. - -## Configuration - -The configuration is as follows: -```yaml -duo_api: - disable: false - hostname: api-123456789.example.com - integration_key: ABCDEF - secret_key: 1234567890abcdefghifjkl - enable_self_enrollment: false -``` - -The secret key is shown as an example, you also have the option to set it using an environment -variable as described [here](./secrets.md). - -## Options - -### disable: -
-type: boolean -{: .label .label-config .label-purple } -default: false -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -Disables Duo. If the hostname, integration_key, and secret_key are all empty strings or undefined this is automatically -true. - -### hostname -
-type: string -{: .label .label-config .label-purple } -default: "" -{: .label .label-config .label-blue } -required: yes -{: .label .label-config .label-red } -
- -The [Duo] API hostname supplied by [Duo]. - -### integration_key -
-type: string -{: .label .label-config .label-purple } -default: "" -{: .label .label-config .label-blue } -required: yes -{: .label .label-config .label-red } -
- -The non-secret [Duo] integration key. Similar to a client identifier. - -### secret_key -
-type: string -{: .label .label-config .label-purple } -default: "" -{: .label .label-config .label-blue } -required: yes -{: .label .label-config .label-red } -
- -The secret [Duo] key used to verify your application is valid. - -### enable_self_enrollment -
-type: boolean -{: .label .label-config .label-purple } -default: false -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -Enables [Duo] device self-enrollment from within the Authelia portal. - -[Duo]: https://duo.com/ diff --git a/docs/configuration/identity-providers/index.md b/docs/configuration/identity-providers/index.md deleted file mode 100644 index d3b93e5d0..000000000 --- a/docs/configuration/identity-providers/index.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -layout: default -title: Identity Providers -parent: Configuration -nav_order: 4 -has_children: true ---- - -# Identity Providers - -This section covers configuration of the identity server characteristics of Authelia. Currently the only identity server -supported is OpenID Connect. diff --git a/docs/configuration/identity-providers/oidc.md b/docs/configuration/identity-providers/oidc.md deleted file mode 100644 index eda2af788..000000000 --- a/docs/configuration/identity-providers/oidc.md +++ /dev/null @@ -1,656 +0,0 @@ ---- -layout: default -title: OpenID Connect -parent: Identity Providers -grand_parent: Configuration -nav_order: 2 ---- - -# OpenID Connect - -**Authelia** currently supports the [OpenID Connect] OP role as a [**beta**](../../roadmap/oidc.md) feature. The OP role -is the [OpenID Connect] Provider role, not the Relying Party or RP role. This means other applications that implement the -[OpenID Connect] RP role can use Authelia as an authentication and authorization backend similar to how you may use -social media or development platforms for login. - -The Relying Party role is the role which allows an application to use GitHub, Google, or other [OpenID Connect] -providers for authentication and authorization. We do not intend to support this functionality at this moment in time. - -More information about the beta can be found in the [roadmap](../../roadmap/oidc.md). - -## Configuration - -The following snippet provides a sample-configuration for the OIDC identity provider explaining each field in detail. - -```yaml -identity_providers: - oidc: - hmac_secret: this_is_a_secret_abc123abc123abc - issuer_private_key: | - --- KEY START - --- KEY END - access_token_lifespan: 1h - authorize_code_lifespan: 1m - id_token_lifespan: 1h - refresh_token_lifespan: 90m - enable_client_debug_messages: false - enforce_pkce: public_clients_only - cors: - endpoints: - - authorization - - token - - revocation - - introspection - allowed_origins: - - https://example.com - allowed_origins_from_client_redirect_uris: false - clients: - - id: myapp - description: My Application - secret: this_is_a_secret - sector_identifier: '' - public: false - authorization_policy: two_factor - pre_configured_consent_duration: '' - audience: [] - scopes: - - openid - - groups - - email - - profile - redirect_uris: - - https://oidc.example.com:8080/oauth2/callback - grant_types: - - refresh_token - - authorization_code - response_types: - - code - response_modes: - - form_post - - query - - fragment - userinfo_signing_algorithm: none -``` - -## Options - -### hmac_secret -
-type: string -{: .label .label-config .label-purple } -required: yes -{: .label .label-config .label-red } -
- -The HMAC secret used to sign the [OpenID Connect] JWT's. The provided string is hashed to a SHA256 -byte string for the purpose of meeting the required format. You must [generate this option yourself](#generating-a-random-secret). - -Should be defined using a [secret](../secrets.md) which is the recommended for containerized deployments. - -### issuer_private_key -
-type: string -{: .label .label-config .label-purple } -required: yes -{: .label .label-config .label-red } -
- -The private key in DER base64 encoded PEM format used to encrypt the [OpenID Connect] JWT's.[¹](../../faq.md#why-only-use-a-private-issuer-key-and-no-public-key-with-oidc) -You must [generate this option yourself](#generating-a-random-secret). To create this option, use -`docker run -u "$(id -u):$(id -g)" -v "$(pwd)":/keys authelia/authelia:latest authelia rsa generate --dir /keys` -to generate both the private and public key in the current directory. You can then paste the -private key into your configuration. - -Should be defined using a [secret](../secrets.md) which is the recommended for containerized deployments. - -### access_token_lifespan -
-type: duration -{: .label .label-config .label-purple } -default: 1h -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -The maximum lifetime of an access token. It's generally recommended keeping this short similar to the default. -For more information read these docs about [token lifespan]. - -### authorize_code_lifespan -
-type: duration -{: .label .label-config .label-purple } -default: 1m -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -The maximum lifetime of an authorize code. This can be rather short, as the authorize code should only be needed to -obtain the other token types. For more information read these docs about [token lifespan]. - -### id_token_lifespan -
-type: duration -{: .label .label-config .label-purple } -default: 1h -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -The maximum lifetime of an ID token. For more information read these docs about [token lifespan]. - -### refresh_token_lifespan -
-type: string -{: .label .label-config .label-purple } -default: 90m -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -The maximum lifetime of a refresh token. The -refresh token can be used to obtain new refresh tokens as well as access tokens or id tokens with an -up-to-date expiration. For more information read these docs about [token lifespan]. - -A good starting point is 50% more or 30 minutes more (which ever is less) time than the highest lifespan out of the -[access token lifespan](#access_token_lifespan), the [authorize code lifespan](#authorize_code_lifespan), and the -[id token lifespan](#id_token_lifespan). For instance the default for all of these is 60 minutes, so the default refresh -token lifespan is 90 minutes. - -### enable_client_debug_messages -
-type: boolean -{: .label .label-config .label-purple } -default: false -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -Allows additional debug messages to be sent to the clients. - -### minimum_parameter_entropy -
-type: integer -{: .label .label-config .label-purple } -default: 8 -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -This controls the minimum length of the `nonce` and `state` parameters. - -***Security Notice:*** Changing this value is generally discouraged, reducing it from the default can theoretically -make certain scenarios less secure. It is highly encouraged that if your OpenID Connect RP does not send these parameters -or sends parameters with a lower length than the default that they implement a change rather than changing this value. - -### enforce_pkce -
-type: string -{: .label .label-config .label-purple } -default: public_clients_only -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -[Proof Key for Code Exchange](https://datatracker.ietf.org/doc/html/rfc7636) enforcement policy: if specified, must be either `never`, `public_clients_only` or `always`. - -If set to `public_clients_only` (default), PKCE will be required for public clients using the Authorization Code flow. - -When set to `always`, PKCE will be required for all clients using the Authorization Code flow. - -***Security Notice:*** Changing this value to `never` is generally discouraged, reducing it from the default can theoretically -make certain client-side applications (mobile applications, SPA) vulnerable to CSRF and authorization code interception attacks. - -### enable_pkce_plain_challenge -
-type: boolean -{: .label .label-config .label-purple } -default: false -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -Allows PKCE `plain` challenges when set to `true`. - -***Security Notice:*** Changing this value is generally discouraged. Applications should use the `S256` PKCE challenge method instead. - -### cors - -Some OpenID Connect Endpoints need to allow cross-origin resource sharing, however some are optional. This section allows -you to configure the optional parts. We reply with CORS headers when the request includes the Origin header. - -#### endpoints -
-type: list(string) -{: .label .label-config .label-purple } -default: empty -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -A list of endpoints to configure with cross-origin resource sharing headers. It is recommended that the `userinfo` -option is at least in this list. The potential endpoints which this can be enabled on are as follows: - -* authorization -* token -* revocation -* introspection -* userinfo - -#### allowed_origins -
-type: list(string) -{: .label .label-config .label-purple } -default: empty -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -A list of permitted origins. - -Any origin with https is permitted unless this option is configured or the allowed_origins_from_client_redirect_uris -option is enabled. This means you must configure this option manually if you want http endpoints to be permitted to -make cross-origin requests to the OpenID Connect endpoints, however this is not recommended. - -Origins must only have the scheme, hostname and port, they may not have a trailing slash or path. - -In addition to an Origin URI, you may specify the wildcard origin in the allowed_origins. It MUST be specified by itself -and the allowed_origins_from_client_redirect_uris MUST NOT be enabled. The wildcard origin is denoted as `*`. Examples: - -```yaml -identity_providers: - oidc: - cors: - allowed_origins: "*" -``` - -```yaml -identity_providers: - oidc: - cors: - allowed_origins: - - "*" -``` - -#### allowed_origins_from_client_redirect_uris -
-type: boolean -{: .label .label-config .label-purple } -default: false -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -Automatically adds the origin portion of all redirect URI's on all clients to the list of allowed_origins, provided they -have the scheme http or https and do not have the hostname of localhost. - -### clients - -A list of clients to configure. The options for each client are described below. - -#### id -
-type: string -{: .label .label-config .label-purple } -required: yes -{: .label .label-config .label-red } -
- -The Client ID for this client. It must exactly match the Client ID configured in the application -consuming this client. - -#### description -
-type: string -{: .label .label-config .label-purple } -default: *same as id* -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -A friendly description for this client shown in the UI. This defaults to the same as the ID. - -#### secret -
-type: string -{: .label .label-config .label-purple } -required: situational -{: .label .label-config .label-yellow } -
- -The shared secret between Authelia and the application consuming this client. This secret must -match the secret configured in the application. Currently this is stored in plain text. -You must [generate this option yourself](#generating-a-random-secret). - -This must be provided when the client is a confidential client type, and must be blank when using the public client -type. To set the client type to public see the [public](#public) configuration option. - -#### sector_identifier -
-type: string -{: .label .label-config .label-purple } -default: '' -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-red } -
- -_**Important Note:** because adjusting this option will inevitably change the `sub` claim of all tokens generated for -the specified client, changing this should cause the relying party to detect all future authorizations as completely new -users._ - -Must be an empty string or the host component of a URL. This is commonly just the domain name, but may also include a -port. - -Authelia utilizes UUID version 4 subject identifiers. By default the public subject identifier type is utilized for all -clients. This means the subject identifiers will be the same for all clients. This configuration option enables pairwise -for this client, and configures the sector identifier utilized for both the storage and the lookup of the subject -identifier. - -1. All clients who do not have this configured will generate the same subject identifier for a particular user regardless - of which client obtains the ID token. -2. All clients which have the same sector identifier will: - 1. have the same subject identifier for a particular user when compared to clients with the same sector identifier. - 2. have a completely different subject identifier for a particular user whe compared to: - 1. any client with the public subject identifier type. - 2. any client with a differing sector identifier. - -In specific but limited scenarios this option is beneficial for privacy reasons. In particular this is useful when the -party utilizing the _Authelia_ [OpenID Connect] Authorization Server is foreign and not controlled by the user. It would -prevent the third party utilizing the subject identifier with another third party in order to track the user. - -Keep in mind depending on the other claims they may still be able to perform this tracking and it is not a silver bullet. -There are very few benefits when utilizing this in a homelab or business where no third party is utilizing -the server. - -#### public -
-type: bool -{: .label .label-config .label-purple } -default: false -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -This enables the public client type for this client. This is for clients that are not capable of maintaining -confidentiality of credentials, you can read more about client types in [RFC6749](https://datatracker.ietf.org/doc/html/rfc6749#section-2.1). -This is particularly useful for SPA's and CLI tools. This option requires setting the [client secret](#secret) to a -blank string. - -In addition to the standard rules for redirect URIs, public clients can use the `urn:ietf:wg:oauth:2.0:oob` redirect URI. - -#### authorization_policy -
-type: string -{: .label .label-config .label-purple } -default: two_factor -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -The authorization policy for this client: either `one_factor` or `two_factor`. - -#### pre_configured_consent_duration -
-type: string (duration) -{: .label .label-config .label-purple } -required: no -{: .label .label-config .label-green } -
- -Configuring this enables users of this client to remember their consent as a pre-configured consent. The value is period -of time is in [duration notation format](../index.md#duration-notation-format). The period of time dictates how long a -users choice to remember the pre-configured consent lasts. - -Pre-configured consents are only valid if the subject, client id are exactly the same and the requested scopes/audience -match exactly with the granted scopes/audience. - -#### audience -
-type: list(string) -{: .label .label-config .label-purple } -required: no -{: .label .label-config .label-green } -
- -A list of audiences this client is allowed to request. - -#### scopes -
-type: list(string) -{: .label .label-config .label-purple } -default: openid, groups, profile, email -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -A list of scopes to allow this client to consume. See [scope definitions](#scope-definitions) for more -information. The documentation for the application you want to use with Authelia will most-likely provide -you with the scopes to allow. - -#### redirect_uris -
-type: list(string) -{: .label .label-config .label-purple } -required: yes -{: .label .label-config .label-red } -
- -A list of valid callback URIs this client will redirect to. All other callbacks will be considered -unsafe. The URIs are case-sensitive and they differ from application to application - the community has -provided [a list of URL´s for common applications](../../community/oidc-integrations.md). - -Some restrictions that have been placed on clients and -their redirect URIs are as follows: - -1. If a client attempts to authorize with Authelia and its redirect URI is not listed in the client configuration the - attempt to authorize wil fail and an error will be generated. -2. The redirect URIs are case-sensitive. -3. The URI must include a scheme and that scheme must be one of `http` or `https`. -4. The client can ignore rule 3 and use `urn:ietf:wg:oauth:2.0:oob` if it is a [public](#public) client type. - -#### grant_types -
-type: list(string) -{: .label .label-config .label-purple } -default: refresh_token, authorization_code -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -A list of grant types this client can return. _It is recommended that this isn't configured at this time unless you -know what you're doing_. Valid options are: `implicit`, `refresh_token`, `authorization_code`, `password`, -`client_credentials`. - -#### response_types -
-type: list(string) -{: .label .label-config .label-purple } -default: code -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -A list of response types this client can return. _It is recommended that this isn't configured at this time unless you -know what you're doing_. Valid options are: `code`, `code id_token`, `id_token`, `token id_token`, `token`, -`token id_token code`. - -#### response_modes -
-type: list(string) -{: .label .label-config .label-purple } -default: form_post, query, fragment -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -A list of response modes this client can return. It is recommended that this isn't configured at this time unless you -know what you're doing. Potential values are `form_post`, `query`, and `fragment`. - -#### userinfo_signing_algorithm -
-type: string -{: .label .label-config .label-purple } -default: none -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -The algorithm used to sign the userinfo endpoint responses. This can either be `none` or `RS256`. - -## Generating a random secret - -If you must provide a random secret in configuration, you can generate a random string of sufficient length. The command - -```sh -LENGTH=64 -tr -cd '[:alnum:]' < /dev/urandom | fold -w "${LENGTH}" | head -n 1 | tr -d '\n' ; echo -``` - -prints such a string with a length in characters of `${LENGTH}` on `stdout`. The string will only contain alphanumeric -characters. For Kubernetes, see [this section too](../secrets.md#Kubernetes). - -## Scope Definitions - -### openid - -This is the default scope for openid. This field is forced on every client by the configuration validation that Authelia -does. - -_**Important Note:** The subject identifiers or `sub` claim has been changed to a [RFC4122] UUID V4 to identify the -individual user as per the [Subject Identifier Types] specification. Please use the claim `preferred_username` instead._ - -| Claim | JWT Type | Authelia Attribute | Description | -|:---------:|:-------------:|:------------------:|:-----------------------------------------------------------:| -| sub | string | username | A [RFC4122] UUID V4 linked to the user who logged in | -| scope | string | scopes | Granted scopes (space delimited) | -| scp | array[string] | scopes | Granted scopes | -| iss | string | hostname | The issuer name, determined by URL | -| at_hash | string | _N/A_ | Access Token Hash | -| aud | array[string] | _N/A_ | Audience | -| exp | number | _N/A_ | Expires | -| auth_time | number | _N/A_ | The time the user authenticated with Authelia | -| rat | number | _N/A_ | The time when the token was requested | -| iat | number | _N/A_ | The time when the token was issued | -| jti | string(uuid) | _N/A_ | A JWT Identifier in the form of a [RFC4122] UUID V4 | -| amr | array[string] | _N/A_ | An [RFC8176] list of authentication method reference values | -| azp | string | id (client) | The authorized party | -| client_id | string | id (client) | The client id | - -### groups - -This scope includes the groups the authentication backend reports the user is a member of in the token. - -| Claim | JWT Type | Authelia Attribute | Description | -|:------:|:-------------:|:------------------:|:------------------------------------------------------------------------------------------------------------------:| -| groups | array[string] | groups | List of user's groups discovered via [authentication](https://www.authelia.com/docs/configuration/authentication/) | - -### email - -This scope includes the email information the authentication backend reports about the user in the token. - -| Claim | JWT Type | Authelia Attribute | Description | -|:--------------:|:-------------:|:------------------:|:---------------------------------------------------------:| -| email | string | email[0] | The first email address in the list of emails | -| email_verified | bool | _N/A_ | If the email is verified, assumed true for the time being | -| alt_emails | array[string] | email[1:] | All email addresses that are not in the email JWT field | - -### profile - -This scope includes the profile information the authentication backend reports about the user in the token. - -| Claim | JWT Type | Authelia Attribute | Description | -|:------------------:|:--------:|:------------------:|:----------------------------------------:| -| preferred_username | string | username | The username the user used to login with | -| name | string | display_name | The users display name | - -## Authentication Method References - -Authelia currently supports adding the `amr` claim to the [ID Token](https://openid.net/specs/openid-connect-core-1_0.html#IDToken) -utilizing the [RFC8176] Authentication Method Reference values. - -The values this claim has are not strictly defined by the [OpenID Connect] specification. As such, some backends may -expect a specification other than [RFC8176] for this purpose. If you have such an application and wish for us to support -it then you're encouraged to create an issue. - -Below is a list of the potential values we place in the claim and their meaning: - -| Value | Description | Factor | Channel | -|:-----:|:----------------------------------------------------------------:|:------:|:--------:| -| mfa | User used multiple factors to login (see factor column) | N/A | N/A | -| mca | User used multiple channels to login (see channel column) | N/A | N/A | -| user | User confirmed they were present when using their hardware key | N/A | N/A | -| pin | User confirmed they are the owner of the hardware key with a pin | N/A | N/A | -| pwd | User used a username and password to login | Know | Browser | -| otp | User used TOTP to login | Have | Browser | -| hwk | User used a hardware key to login | Have | Browser | -| sms | User used Duo to login | Have | External | - -## Endpoint Implementations - -The following section documents the endpoints we implement and their respective paths. This information can traditionally -be discovered by relying parties that utilize [discovery](https://openid.net/specs/openid-connect-discovery-1_0.html), -however this information may be useful for clients which do not implement this. - -The endpoints can be discovered easily by visiting the Discovery and Metadata endpoints. It is recommended regardless -of your version of Authelia that you utilize this version as it will always produce the correct endpoint URLs. The paths -for the Discovery/Metadata endpoints are part of IANA's well known registration but are also documented in a table below. - -These tables document the endpoints we currently support and their paths in the most recent version of Authelia. The paths -are appended to the end of the primary URL used to access Authelia. The tables use the url https://auth.example.com as -an example of the Authelia root URL which is also the OpenID Connect issuer. - -### Well Known Discovery Endpoints - -These endpoints can be utilized to discover other endpoints and metadata about the Authelia OP. - -| Endpoint | Path | -|:-----------------------------------------:|:---------------------------------------------------------------:| -| [OpenID Connect Discovery] | https://auth.example.com/.well-known/openid-configuration | -| [OAuth 2.0 Authorization Server Metadata] | https://auth.example.com/.well-known/oauth-authorization-server | - - -### Discoverable Endpoints - -These endpoints implement OpenID Connect elements. - -| Endpoint | Path | Discovery Attribute | -|:-------------------:|:-----------------------------------------------:|:----------------------:| -| [JSON Web Key Sets] | https://auth.example.com/jwks.json | jwks_uri | -| [Authorization] | https://auth.example.com/api/oidc/authorization | authorization_endpoint | -| [Token] | https://auth.example.com/api/oidc/token | token_endpoint | -| [Userinfo] | https://auth.example.com/api/oidc/userinfo | userinfo_endpoint | -| [Introspection] | https://auth.example.com/api/oidc/introspection | introspection_endpoint | -| [Revocation] | https://auth.example.com/api/oidc/revocation | revocation_endpoint | - -[JSON Web Key Sets]: https://datatracker.ietf.org/doc/html/rfc7517#section-5 -[OpenID Connect]: https://openid.net/connect/ -[Subject Identifier Types]:https://openid.net/specs/openid-connect-core-1_0.html#SubjectIDTypes -[OpenID Connect Discovery]: https://openid.net/specs/openid-connect-discovery-1_0.html -[OAuth 2.0 Authorization Server Metadata]: https://datatracker.ietf.org/doc/html/rfc8414 -[Authorization]: https://openid.net/specs/openid-connect-core-1_0.html#AuthorizationEndpoint -[Token]: https://openid.net/specs/openid-connect-core-1_0.html#TokenEndpoint -[Userinfo]: https://openid.net/specs/openid-connect-core-1_0.html#UserInfo -[Introspection]: https://datatracker.ietf.org/doc/html/rfc7662 -[Revocation]: https://datatracker.ietf.org/doc/html/rfc7009 -[RFC8176]: https://datatracker.ietf.org/doc/html/rfc8176 -[RFC4122]: https://datatracker.ietf.org/doc/html/rfc4122 -[token lifespan]: https://docs.apigee.com/api-platform/antipatterns/oauth-long-expiration \ No newline at end of file diff --git a/docs/configuration/index.md b/docs/configuration/index.md deleted file mode 100644 index c107ecd34..000000000 --- a/docs/configuration/index.md +++ /dev/null @@ -1,209 +0,0 @@ ---- -layout: default -title: Configuration -nav_order: 4 -has_children: true ---- - -# Configuration -Authelia has several methods of configuration available to it. The order of precedence is as follows: - -1. [Secrets](./secrets.md) -2. [Environment Variables](#environment) -3. [Files](#files) (in order of them being specified) - -This order of precedence puts higher weight on things higher in the list. This means anything specified in the -[files](#files) is overridden by [environment variables](#environment) if specified, and anything specified by -[environment variables](#environment) is overridden by [secrets](./secrets.md) if specified. - -## Files -When running **Authelia**, you can specify your configuration by passing the file path as shown below. - -```console -$ authelia --config config.custom.yml -``` - -You can have multiple configuration files which will be merged in the order specified. If duplicate keys are specified -the last one to be specified is the one that takes precedence. Example: - -```console -$ authelia --config configuration.yml --config config-acl.yml --config config-other.yml -$ authelia --config configuration.yml,config-acl.yml,config-other.yml -``` - -Authelia's configuration files use the YAML format. A template with all possible options can be found at the root of the -repository [here](https://github.com/authelia/authelia/blob/master/config.template.yml). - -### Docker -By default, the container looks for a configuration file at `/config/configuration.yml`. This can be changed using the `command` setting. - -## Environment -You may also provide the configuration by using environment variables. Environment variables are applied after the -configuration file meaning anything specified as part of the environment overrides the configuration files. The -environment variables must be prefixed with `AUTHELIA_`. - -_**Please Note:** It is not possible to configure_ the _access control rules section or OpenID Connect identity provider -section using environment variables at this time._ - -_**Please Note:** There are compatability issues with Kubernetes and this particular configuration option. You must -ensure you have the `enableServiceLinks: false` setting in your pod spec. You can read more about this in the -[migration documentation](./migration.md#kubernetes-4300)._ - -Underscores replace indented configuration sections or subkeys. For example the following environment variables replace -the configuration snippet that follows it: - -``` -AUTHELIA_LOG_LEVEL=info -AUTHELIA_SERVER_READ_BUFFER_SIZE=4096 -``` - -```yaml -log: - level: info -server: - read_buffer_size: 4096 -``` - -# Documentation - -We document the configuration in two ways: - -1. The configuration yaml default has comments documenting it. All documentation lines start with `##`. Lines starting - with a single `#` are yaml configuration options which are commented to disable them or as examples. - -2. This documentation site. Generally each section of the configuration is in its own section of the documentation - site. Each configuration option is listed in its relevant section as a heading, under that heading generally are two - or three colored labels. - - The `type` label is purple and indicates the yaml value type of the variable. It optionally includes some - additional information in parentheses. - - The `default` label is blue and indicates the default value if you don't define the option at all. This is not the - same value as you will see in the examples in all instances, it is the value set when blank or undefined. - - The `required` label changes color. When required it will be red, when not required it will be green, when the - required state depends on another configuration value it is yellow. - -# Validation - -Authelia validates the configuration when it starts. This process checks multiple factors including configuration keys -that don't exist, configuration keys that have changed, the values of the keys are valid, and that a configuration -key isn't supplied at the same time as a secret for the same configuration option. - -You may also optionally validate your configuration against this validation process manually by using the validate-config -option with the Authelia binary as shown below. Keep in mind if you're using [secrets](./secrets.md) you will have to -manually provide these if you don't want to get certain validation errors (specifically requesting you provide one of -the secret values). You can choose to ignore them if you know what you're doing. This command is useful prior to -upgrading to prevent configuration changes from impacting downtime in an upgrade. This process does not validate -integrations, it only checks that your configuration syntax is valid. - -```console -$ authelia validate-config --config configuration.yml -``` - -# Regex - -We have several sections of configuration that utilize regular expressions. It's recommended to validate your regex -manually either via tools like [Rego](https://regoio.herokuapp.com/) or some other means. - -It's important when attempting to utilize a backslash that it's utilized correctly. The YAML parser is likely to parse -this as you trying to use YAML escape syntax instead of regex escape syntax. To avoid this use single quotes instead of -no quotes or double quotes. - -Good Example: - -```yaml -domain_regex: '^(admin|secure)\.example\.com$' -``` - -Bad Example: - -```yaml -domain_regex: "^(admin|secure)\.example\.com$" -``` - -# Duration Notation Format - -We have implemented a string/integer based notation for configuration options that take a duration of time. This section -describes the implementation of this. You can use this implementation in various areas of configuration such as: - -- session: - - expiration - - inactivity - - remember_me_duration -- regulation: - - ban_time - - find_time -- ntp: - - max_desync -- webauthn: - - timeout - -The way this format works is you can either configure an integer or a string in the specific configuration areas. If you -supply an integer, it is considered a representation of seconds. If you supply a string, it parses the string in blocks -of quantities and units (number followed by a unit letter). For example `5h` indicates a quantity of 5 units of `h`. - -While you can use multiple of these blocks in combination, ee suggest keeping it simple and use a single value. - -## Duration Notation Format Unit Legend - -| Unit | Associated Letter | -|:-------:|:-----------------:| -| Years | y | -| Months | M | -| Weeks | w | -| Days | d | -| Hours | h | -| Minutes | m | -| Seconds | s | - -## Duration Notation Format Examples - -| Desired Value | Configuration Examples | -|:---------------------:|:-------------------------------------:| -| 1 hour and 30 minutes | `90m` or `1h30m` or `5400` or `5400s` | -| 1 day | `1d` or `24h` or `86400` or `86400s` | -| 10 hours | `10h` or `600m` or `9h60m` or `36000` | - -# TLS Configuration - -Various sections of the configuration use a uniform configuration section called TLS. Notably LDAP and SMTP. -This section documents the usage. - -## Server Name -
-type: string -{: .label .label-config .label-purple } -default: "" -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -The key `server_name` overrides the name checked against the certificate in the verification process. Useful if you -require to use a direct IP address for the address of the backend service but want to verify a specific SNI. - -## Skip Verify -
-type: boolean -{: .label .label-config .label-purple } -default: false -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -The key `skip_verify` completely negates validating the certificate of the backend service. This is not recommended, -instead you should tweak the `server_name` option, and the global option [certificates directory](./miscellaneous.md#certificates_directory). - -## Minimum Version -
-type: string -{: .label .label-config .label-purple } -default: TLS1.2 -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -The key `minimum_version` controls the minimum TLS version Authelia will use when opening TLS connections. -The possible values are `TLS1.3`, `TLS1.2`, `TLS1.1`, `TLS1.0`. Anything other than `TLS1.3` or `TLS1.2` -are very old and deprecated. You should avoid using these and upgrade your backend service instead of decreasing -this value. diff --git a/docs/configuration/migration.md b/docs/configuration/migration.md deleted file mode 100644 index f1022320b..000000000 --- a/docs/configuration/migration.md +++ /dev/null @@ -1,95 +0,0 @@ ---- -layout: default -title: Migration -parent: Configuration -nav_order: 6 ---- - -This section documents changes in the configuration which may require manual migration by the administrator. Typically -this only occurs when a configuration key is renamed or moved to a more appropriate location. - -## Format - -The migrations are formatted in a table with the old key and the new key. Periods indicate a different section which can -be represented in YAML as a dictionary i.e. it's indented. - -In our table `server.host` with a value of `0.0.0.0` is represented in YAML like this: - -```yaml -server: - host: 0.0.0.0 -``` - -## Policy -Our deprecation policy for configuration keys is 3 minor versions. For example if a configuration option is deprecated -in version 4.30.0, it will remain as a warning for 4.30.x, 4.31.x, and 4.32.x; then it will become a fatal error in -4.33.0+. - -## Migrations - -### 4.33.0 -The options deprecated in version [4.30.0](#4300) have been fully removed as per our deprecation policy and warnings -logged for users. - -### 4.30.0 -The following changes occurred in 4.30.0: - -| Previous Key | New Key | -|:-------------:|:----------------------:| -| host | server.host | -| port | server.port | -| tls_key | server.tls.key | -| tls_cert | server.tls.certificate | -| log_level | log.level | -| log_file_path | log.file_path | -| log_format | log.format | - -_**Please Note:** you can no longer define secrets for providers that you are not using. For example if you're using the -[filesystem notifier](./notifier/filesystem.md) you must ensure that the `AUTHELIA_NOTIFIER_SMTP_PASSWORD_FILE` -environment variable or other environment variables set. This also applies to other providers like -[storage](./storage/index.md) and [authentication backend](./authentication/index.md)._ - -#### Kubernetes 4.30.0 - -_**Please Note:** if you're using Authelia with Kubernetes and are not using the provided [helm chart](https://charts.authelia.com) -you will be required to set the following option in your PodSpec. Keeping in mind this example is for a Pod, not for -a Deployment, StatefulSet, or DaemonSet; you will need to adapt the `enableServiceLinks` option to fit into the relevant -location depending on your needs._ - -```yaml ---- -apiVersion: v1 -kind: Pod -metadata: - name: authelia -spec: - enableServiceLinks: false -... -``` - -### 4.25.0 - -The following changes occurred in 4.25.0: - -|Previous Key |New Key | -|:---------------------------------------------:|:---------------------------------------------:| -|authentication_backend.ldap.tls.skip_verify |authentication_backend.ldap.tls.skip_verify | -|authentication_backend.ldap.minimum_tls_version|authentication_backend.ldap.tls.minimum_version| -|notifier.smtp.disable_verify_cert |notifier.smtp.tls.skip_verify | -|notifier.smtp.trusted_cert |certificates_directory | - -_**Please Note:** `certificates_directory` is not a direct replacement for the `notifier.smtp.trusted_cert`, instead -of being the path to a specific file it is a path to a directory containing certificates trusted by Authelia. This -affects other services like LDAP as well._ - -### 4.7.0 - -The following changes occurred in 4.7.0: - -|Previous Key|New Key | -|:----------:|:-------:| -|logs_level |log_level| -|logs_file |log_file | - -_**Please Note:** The new keys also changed in [4.30.0](#4.30.0) so you will need to update them to the new values if you -are using [4.30.0](#4.30.0) or newer instead of the new keys listed here._ diff --git a/docs/configuration/notifier/filesystem.md b/docs/configuration/notifier/filesystem.md deleted file mode 100644 index bb5123821..000000000 --- a/docs/configuration/notifier/filesystem.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -layout: default -title: Filesystem -parent: Notifier -grand_parent: Configuration -nav_order: 1 ---- - -# Filesystem - -With this configuration, the message will be sent to a file. This option should only be used for testing purposes. -This method will use the plain text email template for readability purposes. - -## Configuration - -```yaml -notifier: - disable_startup_check: false - filesystem: - filename: /config/notification.txt -``` - -## Options - -### filename -
-type: string -{: .label .label-config .label-purple } -required: yes -{: .label .label-config .label-red } -
- -The file to add email text to. If it doesn't exist it will be created. diff --git a/docs/configuration/notifier/index.md b/docs/configuration/notifier/index.md deleted file mode 100644 index 92ac07e7c..000000000 --- a/docs/configuration/notifier/index.md +++ /dev/null @@ -1,97 +0,0 @@ ---- -layout: default -title: Notifier -parent: Configuration -nav_order: 8 -has_children: true ---- - -# Notifier - -**Authelia** sometimes needs to send messages to users in order to -verify their identity. - -## Configuration - -```yaml -notifier: - disable_startup_check: false - template_path: /path/to/templates/folder - filesystem: {} - smtp: {} -``` - -## Options - -### disable_startup_check -
-type: boolean -{: .label .label-config .label-purple } -default: false -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -The notifier has a startup check which validates the specified provider -configuration is correct and will be able to send emails. This can be -disabled with the `disable_startup_check` option: - -### template_path -
-type: string -{: .label .label-config .label-purple } -default: "" -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -This option allows the administrator to set a path where custom templates for notifications can be found. Each template -has two extensions; `.html` for HTML templates, and `.txt` for plaintext templates. - -| Template | Description | -|:--------------------:|:-----------------------------------------------------------------------------------------------:| -| IdentityVerification | Template used when registering devices or resetting passwords | -| PasswordReset | Template used to send the notification to users when their password has successfully been reset | - -For example, to modify the `IdentityVerification` HTML template, if your `template_path` was `/config/email_templates`, -you would create the `/config/email_templates/IdentityVerification.html` file. - -_**Note:** you may configure this directory and add only add the templates you wish to override, any templates not -supplied in this folder will utilize the default templates._ - - -In template files, you can use the following variables: - -| Placeholder | Templates | Description | -|:-----------------------------------------:|:--------------------:|:---------------------------------------------------------------------------------------------------------------------------------------------:| -| `{% raw %}{{ .LinkURL }}{% endraw %}` | IdentityVerification | The URL of the used with the IdentityVerification template. | -| `{% raw %}{{ .LinkText }}{% endraw %}` | IdentityVerification | The display value for the IdentityVerification button intended for the link. | -| `{% raw %}{{ .Title }}{% endraw %}` | All | A predefined title for the email.
It will be `"Reset your password"` or `"Password changed successfully"`, depending on the current step | -| `{% raw %}{{ .DisplayName }}{% endraw %}` | All | The name of the user, i.e. `John Doe` | -| `{% raw %}{{ .RemoteIP }}{% endraw %}` | All | The remote IP address that initiated the request or event | - -#### Examples - -This is a basic example: - -```html - -

{{ .Title }}

- Hi {{ .DisplayName }}
- This email has been sent to you in order to validate your identity. - Click here to change your password. - -``` - -Some Additional examples for specific purposes can be found in the -[examples directory on GitHub](https://github.com/authelia/authelia/tree/master/examples/templates/notifications). - -### filesystem - -The [filesystem](filesystem.md) provider. - -### smtp - -The [smtp](smtp.md) provider. diff --git a/docs/configuration/ntp.md b/docs/configuration/ntp.md deleted file mode 100644 index 20fbe34f9..000000000 --- a/docs/configuration/ntp.md +++ /dev/null @@ -1,91 +0,0 @@ ---- -layout: default -title: NTP -parent: Configuration -nav_order: 9 ---- - -# NTP - -Authelia has the ability to check the system time against an NTP server. Currently this only occurs at startup. This -section configures and tunes the settings for this check which is primarily used to ensure [TOTP](./one-time-password.md) -can be accurately validated. - -In the instance of inability to contact the NTP server Authelia will just log an error and will continue to run. - -## Configuration - -```yaml -ntp: - address: "time.cloudflare.com:123" - version: 3 - max_desync: 3s - disable_startup_check: false - disable_failure: false -``` - -## Options - -### address -
-type: string -{: .label .label-config .label-purple } -default: time.cloudflare.com:123 -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -Determines the address of the NTP server to retrieve the time from. The format is `:`, and both of these are -required. - -### version -
-type: integer -{: .label .label-config .label-purple } -default: 4 -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -Determines the NTP verion supported. Valid values are 3 or 4. - -### max_desync -
-type: duration -{: .label .label-config .label-purple } -default: 3s -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -This is used to tune the acceptable desync from the time reported from the NTP server. This uses our -[duration notation](./index.md#duration-notation-format) format. - -### disable_startup_check -
-type: boolean -{: .label .label-config .label-purple } -default: false -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -Setting this to true will disable the startup check entirely. - -### disable_failure -
-type: boolean -{: .label .label-config .label-purple } -default: false -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -Setting this to true will allow Authelia to start and just log an error instead of exiting. The default is that if -Authelia can contact the NTP server successfully, and the time reported by the server is greater than what is configured -in [max_desync](#max_desync) that Authelia fails to start and logs a fatal error. \ No newline at end of file diff --git a/docs/configuration/password_policy.md b/docs/configuration/password_policy.md deleted file mode 100644 index d673e1bd6..000000000 --- a/docs/configuration/password_policy.md +++ /dev/null @@ -1,161 +0,0 @@ ---- -layout: default -title: Password Policy -parent: Configuration -nav_order: 18 ---- - -# Password Policy - -_Authelia_ allows administrators to configure an enforced password policy. - -## Configuration - -```yaml -password_policy: - standard: - enabled: false - min_length: 8 - max_length: 0 - require_uppercase: false - require_lowercase: false - require_number: false - require_special: false - zxcvbn: - enabled: false - min_score: 3 -``` - -## Options - -### standard -
-type: list -{: .label .label-config .label-purple } -required: no -{: .label .label-config .label-green } -
- -This section allows you to enable standard security policies. - -#### enabled -
-type: boolean -{: .label .label-config .label-purple } -default: false -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -Enables standard password policy. - -#### min_length -
-type: integer -{: .label .label-config .label-purple } -default: 8 -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -Determines the minimum allowed password length. - -#### max_length -
-type: integer -{: .label .label-config .label-purple } -default: 0 -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -Determines the maximum allowed password length. - -#### require_uppercase -
-type: boolean -{: .label .label-config .label-purple } -default: false -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -Indicates that at least one UPPERCASE letter must be provided as part of the password. - -#### require_lowercase -
-type: boolean -{: .label .label-config .label-purple } -default: false -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -Indicates that at least one lowercase letter must be provided as part of the password. - -#### require_number -
-type: boolean -{: .label .label-config .label-purple } -default: false -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -Indicates that at least one number must be provided as part of the password. - -#### require_special -
-type: boolean -{: .label .label-config .label-purple } -default: false -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -Indicates that at least one special character must be provided as part of the password. - -### zxcvbn - -This password policy enables advanced password strength metering, using [zxcvbn](https://github.com/dropbox/zxcvbn). - -#### enabled -
-type: boolean -{: .label .label-config .label-purple } -default: false -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -_**Important Note:** only one password policy can be applied at a time._ - -Enables zxcvbn password policy. - -#### min_score -
-type: integer -{: .label .label-config .label-purple } -default: 3 -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -Configures the minimum zxcvbn score allowed for new passwords. There are 5 levels in the zxcvbn score system (taken from [github.com/dropbox/zxcvbn](https://github.com/dropbox/zxcvbn#usage)): - -- score 0: too guessable: risky password (guesses < 10^3) -- score 1: very guessable: protection from throttled online attacks (guesses < 10^6) -- score 2: somewhat guessable: protection from unthrottled online attacks. (guesses < 10^8) -- score 3: safely unguessable: moderate protection from offline slow-hash scenario. (guesses < 10^10) -- score 4: very unguessable: strong protection from offline slow-hash scenario. (guesses >= 10^10) - -We do not allow score 0, if you set the `min_score` value to 0 instead the default will be chosen. \ No newline at end of file diff --git a/docs/configuration/regulation.md b/docs/configuration/regulation.md deleted file mode 100644 index 5f3815fc1..000000000 --- a/docs/configuration/regulation.md +++ /dev/null @@ -1,61 +0,0 @@ ---- -layout: default -title: Regulation -parent: Configuration -nav_order: 10 ---- - -# Regulation - -**Authelia** can temporarily ban accounts when there are too many -authentication attempts. This helps prevent brute-force attacks. - -## Configuration - -```yaml -regulation: - max_retries: 3 - find_time: 2m - ban_time: 5m -``` - -## Options - -### max_retries -
-type: integer -{: .label .label-config .label-purple } -default: 3 -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -The number of failed login attempts before a user may be banned. Setting this option to 0 disables regulation entirely. - -### find_time -
-type: string (duration) -{: .label .label-config .label-purple } -default: 2m -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -The period of time in [duration notation format](index.md#duration-notation-format) analyzed for failed attempts. For -example if you set `max_retries` to 3 and `find_time` to `2m` this means the user must have 3 failed logins in -2 minutes. - -### ban_time -
-type: string (duration) -{: .label .label-config .label-purple } -default: 5m -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -The period of time in [duration notation format](index.md#duration-notation-format) the user is banned for after meeting -the `max_retries` and `find_time` configuration. After this duration the account will be able to login again. diff --git a/docs/configuration/server.md b/docs/configuration/server.md deleted file mode 100644 index adf33dfb6..000000000 --- a/docs/configuration/server.md +++ /dev/null @@ -1,300 +0,0 @@ ---- -layout: default -title: Server -parent: Configuration -nav_order: 12 ---- - -# Server - -The server section configures and tunes the http server module Authelia uses. - -## Configuration - -```yaml -server: - host: 0.0.0.0 - port: 9091 - path: "" - read_buffer_size: 4096 - write_buffer_size: 4096 - enable_pprof: false - enable_expvars: false - disable_healthcheck: false - tls: - key: "" - certificate: "" - client_certificates: [] - headers: - csp_template: "" -``` - -## Options - -## host -
-type: string -{: .label .label-config .label-purple } -default: 0.0.0.0 -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -Defines the address to listen on. See also [port](#port). Should typically be `0.0.0.0` or `127.0.0.1`, the former for -containerized environments and the later for daemonized environments like init.d and systemd. - -Note: If utilising an IPv6 literal address it must be enclosed by square brackets and quoted: - -```yaml -host: "[fd00:1111:2222:3333::1]" -``` - -### port -
-type: integer -{: .label .label-config .label-purple } -default: 9091 -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -Defines the port to listen on. See also [host](#host). - -### path -
-type: string -{: .label .label-config .label-purple } -default: "" -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -Authelia by default is served from the root `/` location, either via its own domain or subdomain. - -Modifying this setting will allow you to serve Authelia out from a specified base path. Please note -that currently only a single level path is supported meaning slashes are not allowed, and only -alphanumeric characters are supported. - -Example: https://auth.example.com/, https://example.com/ -```yaml -server: - path: "" -``` - -Example: https://auth.example.com/authelia/, https://example.com/authelia/ -```yaml -server: - path: authelia -``` - -### asset_path -
-type: string -{: .label .label-config .label-purple } -default: "" -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -Authelia by default serves all static assets from an embedded filesystem in the Go binary. - -Modifying this setting will allow you to override and serve specific assets for Authelia from a specified path. -All files that can be overridden are documented below and must be placed in the `asset_path` with a flat file structure. - -Example: -```console -/config/assets/ -├── favicon.ico -├── logo.png -└── locales/[-[variant]]/.json -``` - -| Asset | File name | -|:-------:|:-------------:| -| Favicon | favicon.ico | -| Logo | logo.png | -| locales | see [locales] | - -### read_buffer_size -
-type: integer -{: .label .label-config .label-purple } -default: 4096 -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -Configures the maximum request size. The default of 4096 is generally sufficient for most use cases. - -### write_buffer_size -
-type: integer -{: .label .label-config .label-purple } -default: 4096 -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -Configures the maximum response size. The default of 4096 is generally sufficient for most use cases. - -### enable_pprof -
-type: boolean -{: .label .label-config .label-purple } -default: false -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -Enables the go pprof endpoints. - -### enable_expvars -
-type: boolean -{: .label .label-config .label-purple } -default: false -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -Enables the go expvars endpoints. - -### disable_healthcheck -
-type: boolean -{: .label .label-config .label-purple } -default: false -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -On startup Authelia checks for the existence of /app/healthcheck.sh and /app/.healthcheck.env and if both of these exist -it writes the configuration vars for the healthcheck to the /app/.healthcheck.env file. In instances where this is not -desirable it's possible to disable these interactions entirely. - -An example situation where this is the case is in Kubernetes when set security policies that prevent writing to the -ephemeral storage of a container or just don't want to enable the internal health check. - -### tls - -Authelia typically listens for plain unencrypted connections. This is by design as most environments allow to -security on lower areas of the OSI model. However it required, if you specify both the [tls key](#key) and -[tls certificate](#certificate) options, Authelia will listen for TLS connections. - -#### key -
-type: string (path) -{: .label .label-config .label-purple } -default: "" -{: .label .label-config .label-blue } -required: situational -{: .label .label-config .label-yellow } -
- -The path to the private key for TLS connections. Must be in DER base64/PEM format. - -#### certificate -
-type: string (path) -{: .label .label-config .label-purple } -default: "" -{: .label .label-config .label-blue } -required: situational -{: .label .label-config .label-yellow } -
- -The path to the public certificate for TLS connections. Must be in DER base64/PEM format. - -#### client_certificates -
-type: list(string) -{: .label .label-config .label-purple } -default: [] -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-yellow } -
- -The list of file paths to certificates used for authenticating clients. Those certificates can be root -or intermediate certificates. If no item is provided mutual TLS is disabled. - - -### headers - -#### csp_template -
-type: string -{: .label .label-config .label-purple } -default: "" -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -This customizes the value of the Content-Security-Policy header. It will replace all instances of `${NONCE}` with the -nonce value of the Authelia react bundle. This is an advanced option to customize and you should do sufficient research -about how browsers utilize and understand this header before attempting to customize it. - -For example, the default CSP template is `default-src 'self'; object-src 'none'; style-src 'self' 'nonce-${NONCE}'`. - -## Additional Notes - -### Buffer Sizes - -The read and write buffer sizes generally should be the same. This is because when Authelia verifies -if the user is authorized to visit a URL, it also sends back nearly the same size response as the request. However -you're able to tune these individually depending on your needs. - -### Asset Overrides - -If replacing the Logo for your Authelia portal it is recommended to upload a transparent PNG of your desired logo. -Authelia will automatically resize the logo to an appropriate size to present in the frontend. - -#### locales - -The locales folder holds folders of internationalization locales. This folder can be utilized to override these locales. -They are the names of locales that are returned by the `navigator.langauge` ECMAScript command. These are generally -those in the [RFC5646 / BCP47 Format](https://datatracker.ietf.org/doc/html/rfc5646) specifically the language codes -from [Crowdin](https://support.crowdin.com/api/language-codes/). - -Each directory has json files which you can explore the format of in the -[internal/server/locales](https://github.com/authelia/authelia/tree/master/internal/server/locales) directory on -GitHub. The important part is the key names you wish to override. Each file represents a translation namespace. The list -of current namespaces are below: - -| Namespace | Purpose | -|:---------:|:-------------------:| -| portal | Portal translations | - -A full example for the `en-US` locale for the portal namespace is `locales/en-US/portal.json`. - -Languages in browsers are supported in two forms. In their language only form such as `en` for English, and in their -variant form such as `en-AU` for English (Australian). If a user has the browser language `en-AU` we automatically load -the `en` and `en-AU` languages, where any keys in the `en-AU` language take precedence over the `en` language, and the -translations for the `en` language only applying when a translation from `en-AU` is not available. - -List of supported languages and variants: - -| Description | Language | Additional Variants | Location | -|:-----------:|:--------:|:-------------------:|:----------------------:| -| English | en | N/A | locales/en/portal.json | -| Spanish | es | N/A | locales/es/portal.json | -| German | de | N/A | locales/de/portal.json | - -_**Important Note** Currently users can only override languages that already exist in this list either by overriding -the language itself, or adding a variant form of that language. If you'd like support for another language feel free -to make a PR. We also encourage people to make PR's for variants where the difference in the variants is important._ - -_**Important Note** Overriding these files will not guarantee any form of stability. Users who planning to utilize these -overrides should either check for changes to the files in the -[en](https://github.com/authelia/authelia/tree/master/internal/server/locales/en) translation prior to upgrading or PR -their translation to ensure it is maintained._ \ No newline at end of file diff --git a/docs/configuration/session/index.md b/docs/configuration/session/index.md deleted file mode 100644 index b555d0c42..000000000 --- a/docs/configuration/session/index.md +++ /dev/null @@ -1,147 +0,0 @@ ---- -layout: default -title: Session -parent: Configuration -nav_order: 13 -has_children: true ---- - -# Session - -**Authelia** relies on session cookies to authenticate users. When the user visits -a website of the protected domain `example.com` for the first time, Authelia detects -that there is no cookie for that user. Consequently, Authelia redirects the user -to the login portal through which the user should authenticate to get a cookie which -is valid for `*.example.com`, meaning all websites of the domain. -At the next request, Authelia receives the cookie associated to the authenticated user -and can then order the reverse proxy to let the request pass through to the application. - -## Configuration - -```yaml -session: - name: authelia_session - domain: example.com - same_site: lax - secret: unsecure_session_secret - expiration: 1h - inactivity: 5m - remember_me_duration: 1M -``` - -## Providers - -There are currently two providers for session storage (three if you count Redis Sentinel as a separate provider): -* Memory (default, stateful, no additional configuration) -* [Redis](./redis.md) (stateless). -* [Redis Sentinel](./redis.md#high_availability) (stateless, highly available). - -### Kubernetes or High Availability - -It's important to note when picking a provider, the stateful providers are not recommended in High Availability -scenarios like Kubernetes. Each provider has a note beside it indicating it is *stateful* or *stateless* the stateless -providers are recommended. - -## Options - -### name -
-type: string -{: .label .label-config .label-purple } -default: authelia_session -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -The name of the session cookie. By default this is set to authelia_session. It's mostly useful to change this if you are -doing development or running multiple instances of Authelia. - -### domain -
-type: string -{: .label .label-config .label-purple } -required: yes -{: .label .label-config .label-red } -
- -The domain the cookie is assigned to protect. This must be the same as the domain Authelia is served on or the root -of the domain. For example if listening on auth.example.com the cookie should be auth.example.com or example.com. - -### same_site -
-type: string -{: .label .label-config .label-purple } -default: lax -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -Sets the cookies SameSite value. Prior to offering the configuration choice this defaulted to None. The new default is -Lax. This option is defined in lower-case. So for example if you want to set it to `Strict`, the value in configuration -needs to be `strict`. - -You can read about the SameSite cookie in detail on the -[MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite). In short setting SameSite to Lax -is generally the most desirable option for Authelia. None is not recommended unless you absolutely know what you're -doing and trust all the protected apps. Strict is not going to work in many use cases and we have not tested it in this -state but it's available as an option anyway. - -### secret -
-type: string -{: .label .label-config .label-purple } -required: yes -{: .label .label-config .label-red } -
- -The secret key used to encrypt session data in Redis. It's recommended this is set using a [secret](../secrets.md). - -### expiration -
-type: string (duration) -{: .label .label-config .label-purple } -default: 1h -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -The time in [duration notation format](../index.md#duration-notation-format) before the cookie expires and the session -is destroyed. This is overriden by remember_me_duration when the remember me box is checked. - -### inactivity -
-type: string (duration) -{: .label .label-config .label-purple } -default: 5m -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -The time in [duration notation format](../index.md#duration-notation-format) the user can be inactive for until the -session is destroyed. Useful if you want long session timers but don't want unused devices to be vulnerable. - -### remember_me_duration -
-type: string (duration) -{: .label .label-config .label-purple } -default: 1M -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -The time in [duration notation format](../index.md#duration-notation-format) the cookie expires and the session is -destroyed when the remember me box is checked. Setting this to `-1` disables this feature entirely. - -## Security - -Configuration of this section has an impact on security. You should read notes in -[security measures](../../security/measures.md#session-security) for more information. - -## Loading a password from a secret instead of inside the configuration - -Password can also be defined using a [secret](../secrets.md). diff --git a/docs/configuration/storage/index.md b/docs/configuration/storage/index.md deleted file mode 100644 index 4b6caae8e..000000000 --- a/docs/configuration/storage/index.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -layout: default -title: Storage Backends -parent: Configuration -nav_order: 14 -has_children: true ---- - -**Authelia** supports multiple storage backends. The backend is used to store user preferences, 2FA device handles and -secrets, authentication logs, etc... - -The available storage backends are listed in the table of contents below. - -## Configuration - -```yaml -storage: - encryption_key: a_very_important_secret - local: {} - mysql: {} - postgres: {} -``` - -## Options - -### encryption_key -
-type: string -{: .label .label-config .label-purple } -required: yes -{: .label .label-config .label-red } -
- -The encryption key used to encrypt data in the database. We encrypt data by creating a sha256 checksum of the provided -value, and use that to encrypt the data with the AES-GCM 256bit algorithm. - -The minimum length of this key is 20 characters, however we generally recommend above 64 characters. - -See [securty measures](../../security/measures.md#storage-security-measures) for more information. - -### local -See [SQLite](./sqlite.md). - -### mysql -See [MySQL](./mysql.md). - -### postgres -See [PostgreSQL](./postgres.md). \ No newline at end of file diff --git a/docs/configuration/storage/mariadb.md b/docs/configuration/storage/mariadb.md deleted file mode 100644 index 8756e6b3c..000000000 --- a/docs/configuration/storage/mariadb.md +++ /dev/null @@ -1,114 +0,0 @@ ---- -layout: default -title: MariaDB -parent: Storage Backends -grand_parent: Configuration -nav_order: 1 ---- - -# MariaDB - -The MySQL storage provider also serves as a MariaDB provider. - -## Version support - -We recommend using the latest version of MariaDB that is officially supported by the MariaDB developers. We also suggest -checking out [PostgreSQL](postgres.md) as an alternative. - -The oldest version of MariaDB that has been tested is 10.6. If using 10.6 you may be required to adjust the -`explicit_defaults_for_timestamp` setting. This will be evident when the container starts with an error similar to -`Error 1067: Invalid default value for 'exp'`. You can adjust this setting in the mysql.cnf file like so: - -```cnf -[mysqld] -explicit_defaults_for_timestamp = 1 -``` - -## Configuration - -```yaml -storage: - encryption_key: a_very_important_secret - mysql: - host: 127.0.0.1 - port: 3306 - database: authelia - username: authelia - password: mypassword -``` - -## Options - -### encryption_key -See the [encryption_key docs](./index.md#encryption_key). - -### host -
-type: string -{: .label .label-config .label-purple } -required: yes -{: .label .label-config .label-red } -
- -The database server host. - -If utilising an IPv6 literal address it must be enclosed by square brackets and quoted: -```yaml -host: "[fd00:1111:2222:3333::1]" -``` - -### port -
-type: integer -{: .label .label-config .label-purple } -default: 3306 -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -The port the database server is listening on. - -### database -
-type: string -{: .label .label-config .label-purple } -required: yes -{: .label .label-config .label-red } -
- -The database name on the database server that the assigned [user](#username) has access to for the purpose of -**Authelia**. - -### username -
-type: string -{: .label .label-config .label-purple } -required: yes -{: .label .label-config .label-red } -
- -The username paired with the password used to connect to the database. - -### password -
-type: string -{: .label .label-config .label-purple } -required: yes -{: .label .label-config .label-red } -
- -The password paired with the username used to connect to the database. Can also be defined using a -[secret](../secrets.md) which is also the recommended way when running as a container. - -### timeout -
-type: duration -{: .label .label-config .label-purple } -default: 5s -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -The SQL connection timeout. diff --git a/docs/configuration/storage/mysql.md b/docs/configuration/storage/mysql.md deleted file mode 100644 index b76874a85..000000000 --- a/docs/configuration/storage/mysql.md +++ /dev/null @@ -1,117 +0,0 @@ ---- -layout: default -title: MySQL -parent: Storage Backends -grand_parent: Configuration -nav_order: 2 ---- - -# MySQL - -The MySQL storage provider. - -## Version support - -We recommend using the latest version of MySQL that is officially supported by the MySQL developers. We also suggest -checking out [PostgreSQL](postgres.md) as an alternative. - -The oldest version of MySQL that has been tested is 5.7. If using 5.7 you may be required to adjust the -`explicit_defaults_for_timestamp` setting. This will be evident when the container starts with an error similar to -`Error 1067: Invalid default value for 'exp'`. You can adjust this setting in the mysql.cnf file like so: - -```cnf -[mysqld] -explicit_defaults_for_timestamp = 1 -``` - -## Configuration - -```yaml -storage: - encryption_key: a_very_important_secret - mysql: - host: 127.0.0.1 - port: 3306 - database: authelia - username: authelia - password: mypassword - timeout: 5s -``` - -## Options - -### encryption_key -See the [encryption_key docs](./index.md#encryption_key). - -### host -
-type: string -{: .label .label-config .label-purple } -default: localhost -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -The database server host. - -If utilising an IPv6 literal address it must be enclosed by square brackets and quoted: -```yaml -host: "[fd00:1111:2222:3333::1]" -``` - -### port -
-type: integer -{: .label .label-config .label-purple } -default: 3306 -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -The port the database server is listening on. - -### database -
-type: string -{: .label .label-config .label-purple } -required: yes -{: .label .label-config .label-red } -
- -The database name on the database server that the assigned [user](#username) has access to for the purpose of -**Authelia**. - -### username -
-type: string -{: .label .label-config .label-purple } -required: yes -{: .label .label-config .label-red } -
- -The username paired with the password used to connect to the database. - -### password -
-type: string -{: .label .label-config .label-purple } -required: yes -{: .label .label-config .label-red } -
- -The password paired with the username used to connect to the database. Can also be defined using a -[secret](../secrets.md) which is also the recommended way when running as a container. - -### timeout -
-type: duration -{: .label .label-config .label-purple } -default: 5s -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -The SQL connection timeout. diff --git a/docs/configuration/storage/postgres.md b/docs/configuration/storage/postgres.md deleted file mode 100644 index 3e2404013..000000000 --- a/docs/configuration/storage/postgres.md +++ /dev/null @@ -1,180 +0,0 @@ ---- -layout: default -title: PostgreSQL -parent: Storage Backends -grand_parent: Configuration -nav_order: 3 ---- - -# PostgreSQL - -The PostgreSQL storage provider. - -## Version support - -See [PostgreSQL support](https://www.postgresql.org/support/versioning/) for the versions supported by PostgreSQL. We -recommend the _current minor_ version of one of the versions supported by PostgreSQL. - -The versions of PostgreSQL that should be supported by Authelia are: -- 14 -- 13 -- 12 -- 11 -- 10 -- 9.6 - -## Configuration - -```yaml -storage: - encryption_key: a_very_important_secret - postgres: - host: 127.0.0.1 - port: 5432 - database: authelia - schema: public - username: authelia - password: mypassword - ssl: - mode: disable - root_certificate: /path/to/root_cert.pem - certificate: /path/to/cert.pem - key: /path/to/key.pem -``` - -## Options - -### encryption_key -See the [encryption_key docs](./index.md#encryption_key). - -### host -
-type: string -{: .label .label-config .label-purple } -required: yes -{: .label .label-config .label-red } -
- -The database server host. - -If utilising an IPv6 literal address it must be enclosed by square brackets and quoted: -```yaml -host: "[fd00:1111:2222:3333::1]" -``` - -### port -
-type: integer -{: .label .label-config .label-purple } -default: 5432 -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -The port the database server is listening on. - -### database -
-type: string -{: .label .label-config .label-purple } -required: yes -{: .label .label-config .label-red } -
- -The database name on the database server that the assigned [user](#username) has access to for the purpose of -**Authelia**. - -### schema -
-type: string -{: .label .label-config .label-purple } -default: public -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -The database schema name to use on the database server that the assigned [user](#username) has access to for the purpose -of **Authelia**. By default this is the public schema. - -### username -
-type: string -{: .label .label-config .label-purple } -required: yes -{: .label .label-config .label-red } -
- -The username paired with the password used to connect to the database. - -### password -
-type: string -{: .label .label-config .label-purple } -required: yes -{: .label .label-config .label-red } -
- -The password paired with the username used to connect to the database. Can also be defined using a -[secret](../secrets.md) which is also the recommended way when running as a container. - -### timeout -
-type: duration -{: .label .label-config .label-purple } -default: 5s -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -The SQL connection timeout. - -### ssl - -#### mode -
-type: string -{: .label .label-config .label-purple } -default: disable -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -SSL mode configures how to handle SSL connections with Postgres. -Valid options are 'disable', 'require', 'verify-ca', or 'verify-full'. -See the [PostgreSQL Documentation](https://www.postgresql.org/docs/12/libpq-ssl.html) -or [pgx - PostgreSQL Driver and Toolkit Documentation](https://pkg.go.dev/github.com/jackc/pgx?tab=doc) -for more information. - -#### root_certificate -
-type: string -{: .label .label-config .label-purple } -required: no -{: .label .label-config .label-green } -
- -The optional location of the root certificate file encoded in the PEM format for validation purposes. - -#### certificate -
-type: string -{: .label .label-config .label-purple } -required: no -{: .label .label-config .label-green } -
- -The optional location of the certificate file encoded in the PEM format for validation purposes. - -#### key -
-type: string -{: .label .label-config .label-purple } -required: no -{: .label .label-config .label-green } -
- -The optional location of the key file encoded in the PEM format for authentication purposes. diff --git a/docs/configuration/storage/sqlite.md b/docs/configuration/storage/sqlite.md deleted file mode 100644 index 5d31d1c97..000000000 --- a/docs/configuration/storage/sqlite.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -layout: default -title: SQLite -parent: Storage Backends -grand_parent: Configuration -nav_order: 4 ---- - -# SQLite - -If you don't have a SQL server, you can use [SQLite](https://en.wikipedia.org/wiki/SQLite). -However please note that this setup will prevent you from running multiple -instances of Authelia since the database will be a local file. - -Use of this storage provider leaves Authelia [stateful](../../features/statelessness.md). It's important in highly -available scenarios to use one of the other providers, and we highly recommend it in production environments, but this -requires you setup an external database such as [PostgreSQL](postgres.md). - -## Configuration - -```yaml -storage: - encryption_key: a_very_important_secret - local: - path: /config/db.sqlite3 -``` - -## Options - -### encryption_key -See the [encryption_key docs](./index.md#encryption_key). - -### path -
-type: string -{: .label .label-config .label-blue } -required: yes -{: .label .label-config .label-red } -
- -The path where the SQLite3 database file will be stored. It will be created if the file does not exist. diff --git a/docs/configuration/theme.md b/docs/configuration/theme.md deleted file mode 100644 index 58ff93bc7..000000000 --- a/docs/configuration/theme.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -layout: default -title: Theme -parent: Configuration -nav_order: 15 ---- - -# Theme - -The theme section configures the theme and style Authelia uses. - -## Configuration - -```yaml -theme: light -``` - -## Options - -### theme -
-type: string -{: .label .label-config .label-purple } -default: light -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
- -There are currently 3 available themes for Authelia: -* light (default) -* dark -* grey - -To enable automatic switching between themes, you can set `theme` to `auto`. The theme will be set to either `dark` or `light` depending on the user's system preference which is determined using media queries. To read more technical details about the media queries used, read the [MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme). diff --git a/docs/content/en/_index.md b/docs/content/en/_index.md new file mode 100644 index 000000000..19273aca8 --- /dev/null +++ b/docs/content/en/_index.md @@ -0,0 +1,8 @@ +--- +title : "Authelia" +description: "Authelia is an open-source authentication and authorization server and portal fulfilling the identity and access management (IAM) role of information security in providing multi-factor authentication and single sign-on (SSO) for your applications via a web portal. It acts as a companion for common reverse proxies." +lead: "Authelia is an open-source authentication and authorization server and portal fulfilling the identity and access management (IAM) role of information security in providing multi-factor authentication and single sign-on (SSO) for your applications via a web portal. It acts as a companion for common reverse proxies." +date: 2020-04-15T15:48:16+02:00 +draft: false +images: [] +--- diff --git a/docs/content/en/blog/_index.md b/docs/content/en/blog/_index.md new file mode 100644 index 000000000..0970d63d1 --- /dev/null +++ b/docs/content/en/blog/_index.md @@ -0,0 +1,7 @@ +--- +title: "Blog" +description: "The Authelia Blog." +date: 2020-04-15T15:48:16+02:00 +draft: false +images: [] +--- diff --git a/docs/content/en/blog/say-hello-to-the-new-website/index.md b/docs/content/en/blog/say-hello-to-the-new-website/index.md new file mode 100644 index 000000000..802bb6df0 --- /dev/null +++ b/docs/content/en/blog/say-hello-to-the-new-website/index.md @@ -0,0 +1,44 @@ +--- +title: "Say hello to the new website 👋" +description: "Introducing the new website" +lead: "Introducing the new website" +date: 2022-03-20T12:52:27+11:00 +draft: false +contributors: ["James Elliott"] +--- + +We're pleased to have you take a look at our new website. It combines both the main landing site and the documentation +all in one neat package. The website is using a [Hugo] theme called [Doks]. + +This does change the development process for documentation slightly compared to what it was previously. However most of +the changes will make it easier for most documentation contributors. This process is documented in the +[Documentation Contributing] section. We will also be looking towards making all +documentation changes getting quickly published to a staging site so they can quickly be seen by the maintainers and +anyone else *too lazy* to follow the steps in the [Documentation Contributing] section command and check it out locally. + +As part of this redesign we've taken the time to rewrite and reorganize key sections of the documentation. This may +result in some links not working, however we've aimed to temporarily redirect links that previously worked to reduce the +number of visitors being presented a 404. + +In particular, you will see improvements in the following areas: + +* The integration documentation is a new area which replaces the deployment documentation: + * There are several additional proxies + * There are several additional deployment scenarios + * It's much better organized + * There are lots of additional links to additional resources to help people find the configuration that suits them + * Several of the proxy configurations have been refreshed to make them more modern + * Some additional docs for k8s now exist +* The roadmap is now heavily documented with stages for areas which require it +* Many areas previously located in the configuration docs have moved into integration docs as that's a more appropriate + area +* The contribution docs have been slightly tidied up + +You may have also noticed we launched a new blog! This blog will be used to communicate key things about the future of +Authelia as well as key things we believe the Authelia community needs to know about. You can subscribe to this blog +via the [RSS Feed](https://www.authelia.com/blog/index.xml). We may introduce a mail list for the blog sometime in the +future. + +[Hugo]: https://gohugo.io/ +[Doks]: https://getdoks.org/ +[Documentation Contributing]: ../../contributing/prologue/documentation.md diff --git a/docs/content/en/configuration/_index.md b/docs/content/en/configuration/_index.md new file mode 100644 index 000000000..528a84bc4 --- /dev/null +++ b/docs/content/en/configuration/_index.md @@ -0,0 +1,8 @@ +--- +title : "Configuration" +description: "Configuration Docs" +lead: "" +date: 2022-03-20T12:52:27+11:00 +draft: false +images: [] +--- diff --git a/docs/content/en/configuration/first-factor/_index.md b/docs/content/en/configuration/first-factor/_index.md new file mode 100644 index 000000000..e8e8032c2 --- /dev/null +++ b/docs/content/en/configuration/first-factor/_index.md @@ -0,0 +1,9 @@ +--- +title : "First Factor" +description: "First Factor methods configuration" +lead: "" +date: 2022-03-20T12:52:27+11:00 +draft: false +images: [] +weight: 102000 +--- diff --git a/docs/content/en/configuration/first-factor/file.md b/docs/content/en/configuration/first-factor/file.md new file mode 100644 index 000000000..c419fdd29 --- /dev/null +++ b/docs/content/en/configuration/first-factor/file.md @@ -0,0 +1,115 @@ +--- +title: "File" +description: "File" +lead: "Authelia supports a file based first factor user provider. This section describes configuring this." +date: 2022-03-20T12:52:27+11:00 +draft: false +images: [] +menu: + configuration: + parent: "first-factor" +weight: 102300 +toc: true +aliases: + - /docs/configuration/authentication/file.html +--- + +## Configuration + +```yaml +authentication_backend: + disable_reset_password: false + file: + path: /config/users.yml + password: + algorithm: argon2id + iterations: 3 + key_length: 32 + salt_length: 16 + parallelism: 4 + memory: 64 +``` + +## Options + +### path + +{{< confkey type="string" required="yes" >}} + +The path to the file with the user details list. Supported file types are: + +* [YAML File](../../reference/guides/passwords.md#yaml-format) + +### password + +#### algorithm + +{{< confkey type="string" default="argon2id" required="no" >}} + +Controls the hashing algorithm used for hashing new passwords. Value must be one of: + +* `argon2id` for the [Argon2] `id` variant +* `sha512` for the [SHA Crypt] `SHA512` variant + +#### iterations + +{{< confkey type="integer" required="no" >}} + +Controls the number of hashing iterations done by the other hashing settings ([Argon2] parameter `t`, [SHA Crypt] +parameter `rounds`). This affects the effective cost of hashing. + +| Algorithm | Minimum | Default | Recommended | +|:---------:|:-------:|:-------:|:------------------------------------------------------------------------------------------:| +| argon2id | 1 | 3 | [See Recommendations](../../reference/guides/passwords.md#recommended-parameters-argon2id) | +| sha512 | 1000 | 50000 | [See Recommendations](../../reference/guides/passwords.md#recommended-parameters-sha512) | + +#### key_length + +{{< confkey type="integer" default="32" required="no" >}} + +*__Important:__ This setting is specific to the `argon2id` algorithm and unused with the `sha512` algorithm.* + +Sets the key length of the [Argon2] hash output. The minimum value is `16` with the recommended value of `32` being set +as the default. + +#### salt_length + +{{< confkey type="integer" default="16" required="no" >}} + +Controls the length of the random salt added to each password before hashing. There is not a compelling reason to have +this set to anything other than `16`, however the minimum is `8` with the recommended value of `16` being set as the +default. + +#### parallelism + +{{< confkey type="integer" default="4" required="no" >}} + +*__Important:__ This setting is specific to the `argon2id` algorithm and unused with the `sha512` algorithm.* + +Sets the number of threads used by [Argon2] when hashing passwords ([Argon2] parameter `p`). The minimum value is `1` +with the recommended value of `4` being set as the default. This affects the effective cost of hashing. + +#### memory + +{{< confkey type="integer" default="64" required="no" >}} + +*__Important:__ This setting is specific to the `argon2id` algorithm and unused with the `sha512` algorithm.* + +Sets the amount of memory in megabytes allocated to a single password hashing calculation ([Argon2] parameter `m`). This +affects the effective cost of hashing. + +This memory is released by go after the hashing process completes, however the operating system may not reclaim the +memory until a later time such as when the system is experiencing memory pressure which may cause the appearance of more +memory being in use than Authelia is actually actively using. Authelia will typically reuse this memory if it has not be +reclaimed as long as another hashing calculation is not still utilizing it. + +## Reference + +A [reference guide](../../reference/guides/passwords.md) exists specifically for choosing password hashing values. This +section contains far more information than is practical to include in this configuration document. See the +[Passwords Reference Guide](../../reference/guides/passwords.md) for more information. + +This guide contains examples such as the [User / Password File](../../reference/guides/passwords.md#user--password-file). + +[Argon2]: https://www.rfc-editor.org/rfc/rfc9106.html +[SHA Crypt]: https://www.akkadia.org/drepper/SHA-crypt.txt diff --git a/docs/content/en/configuration/first-factor/introduction.md b/docs/content/en/configuration/first-factor/introduction.md new file mode 100644 index 000000000..2800d3c9c --- /dev/null +++ b/docs/content/en/configuration/first-factor/introduction.md @@ -0,0 +1,70 @@ +--- +title: "First Factor" +description: "Configuring Authelia First Factor Authentication." +lead: "Authelia uses a username and password for a first factor method. This section describes configuring this." +date: 2022-03-20T12:52:27+11:00 +draft: false +images: [] +menu: + configuration: + parent: "first-factor" +weight: 102100 +toc: true +aliases: + - /c/1fa + - /docs/configuration/authentication/ +--- + +There are two ways to integrate *Authelia* with an authentication backend: + +* [LDAP](ldap.md): users are stored in remote servers like [OpenLDAP], [OpenDJ], [FreeIPA], or + [Microsoft Active Directory]. +* [File](file.md): users are stored in [YAML] file with a hashed version of their password. + +## Configuration + +```yaml +authentication_backend: + refresh_interval: 5m + disable_reset_password: false + password_reset: + custom_url: "" +``` + +## Options + +### refresh_interval + +{{< confkey type="duration" default="5m" required="no" >}} + +This setting controls the interval at which details are refreshed from the backend. Particularly useful for +[LDAP](#ldap). + +### disable_reset_password + +{{< confkey type="boolean" default="false" required="no" >}} + +This setting controls if users can reset their password from the web frontend or not. + +### password_reset + +#### custom_url + +{{< confkey type="string" required="no" >}} + +The custom password reset URL. This replaces the inbuilt password reset functionality and disables the endpoints if +this is configured to anything other than nothing or an empty string. + +### file + +The [file](file.md) authentication provider. + +### ldap + +The [LDAP](ldap.md) authentication provider. + +[OpenLDAP]: https://www.openldap.org/ +[OpenDJ]: https://www.openidentityplatform.org/opendj +[FreeIPA]: https://www.freeipa.org/ +[Microsoft Active Directory]: https://docs.microsoft.com/en-us/windows-server/identity/ad-ds/ad-ds-getting-started +[YAML]: https://yaml.org/ diff --git a/docs/content/en/configuration/first-factor/ldap.md b/docs/content/en/configuration/first-factor/ldap.md new file mode 100644 index 000000000..496f3a338 --- /dev/null +++ b/docs/content/en/configuration/first-factor/ldap.md @@ -0,0 +1,279 @@ +--- +title: "LDAP" +description: "Configuring LDAP" +lead: "Authelia supports an LDAP server based first factor user provider. This section describes configuring this." +date: 2022-03-20T12:52:27+11:00 +draft: false +images: [] +menu: + configuration: + parent: "first-factor" +weight: 102200 +toc: true +aliases: + - /c/ldap + - /docs/configuration/authentication/ldap.html +--- + +## Configuration + +```yaml +authentication_backend: + ldap: + implementation: custom + url: ldap://127.0.0.1 + timeout: 5s + start_tls: false + tls: + server_name: ldap.example.com + skip_verify: false + minimum_version: TLS1.2 + base_dn: DC=example,DC=com + additional_users_dn: ou=users + users_filter: (&({username_attribute}={input})(objectClass=person)) + username_attribute: uid + mail_attribute: mail + display_name_attribute: displayName + additional_groups_dn: ou=groups + groups_filter: (&(member={dn})(objectClass=groupOfNames)) + group_name_attribute: cn + permit_referrals: false + user: CN=admin,DC=example,DC=com + password: password +``` + +## Options + +### implementation + +{{< confkey type="string" default="custom" required="no" >}} + +Configures the LDAP implementation used by Authelia. + +See the [Implementation Guide](#implementation-guide) for information. + +### url + +{{< confkey type="string" required="yes" >}} + +The LDAP URL which consists of a scheme, address, and port. Format is `://
:` or +`://
` where scheme is either `ldap` or `ldaps`. + +```yaml +authentication_backend: + ldap: + url: ldaps://dc1.example.com +``` + +If utilising an IPv6 literal address it must be enclosed by square brackets: + +```yaml +authentication_backend: + ldap: + url: ldap://[fd00:1111:2222:3333::1] +``` + +### timeout + +{{< confkey type="duration" default="5s" required="no" >}} + +The timeout for dialing an LDAP connection. + +### start_tls + +{{< confkey type="boolean" default="false" required="no" >}} + +Enables use of the LDAP StartTLS process which is not commonly used. You should only configure this if you know you need +it. The initial connection will be over plain text, and *Authelia* will try to upgrade it with the LDAP server. LDAPS +URL's are slightly more secure. + +### tls + +Controls the TLS connection validation process. You can see how to configure the tls +section [here](../prologue/common.md#tls-configuration). + +### base_dn + +{{< confkey type="string" required="yes" >}} + +Sets the base distinguished name container for all LDAP queries. If your LDAP domain is example.com this is usually +`DC=example,DC=com`, however you can fine tune this to be more specific for example to only include objects inside the +authelia OU: `OU=authelia,DC=example,DC=com`. This is prefixed with the [additional_users_dn](#additional_users_dn) for +user searches and [additional_groups_dn](#additional_groups_dn) for groups searches. + +### additional_users_dn + +{{< confkey type="string" required="no" >}} + +Additional LDAP path to append to the [base_dn](#base_dn) when searching for users. Useful if you want to restrict +exactly which OU to get users from for either security or performance reasons. For example setting it to +`OU=users,OU=people` with a base_dn set to `DC=example,DC=com` will mean user searches will occur in +`OU=users,OU=people,DC=example,DC=com`. + +### users_filter + +{{< confkey type="string" required="situational" >}} + +*__Note:__ This option is technically required however the [implementation](#implementation) option can implicitly set a +default negating this requirement. Refer to the [filter defaults](#filter-defaults) for more information.* + +The LDAP filter to narrow down which users are valid. This is important to set correctly as to exclude disabled users. +The default value is dependent on the [implementation](#implementation), refer to the +[attribute defaults](#attribute-defaults) for more information. + +### username_attribute + +{{< confkey type="string" required="situational" >}} + +*__Note:__ This option is technically required however the [implementation](#implementation) option can implicitly set a +default negating this requirement. Refer to the [attribute defaults](#attribute-defaults) for more information.* + +The LDAP attribute that maps to the username in *Authelia*. This must contain the `{username_attribute}` +[placeholder](#users-filter-replacements). + +### mail_attribute + +{{< confkey type="string" required="situational" >}} + +*__Note:__ This option is technically required however the [implementation](#implementation) option can implicitly set a +default negating this requirement. Refer to the [attribute defaults](#attribute-defaults) for more information.* + +The attribute to retrieve which contains the users email addresses. This is important for the device registration and +password reset processes. The user must have an email address in order for Authelia to perform identity verification +when a user attempts to reset their password or register a second factor device. + +### display_name_attribute + +{{< confkey type="string" required="situational" >}} + +*__Note:__ This option is technically required however the [implementation](#implementation) option can implicitly set a +default negating this requirement. Refer to the [attribute defaults](#attribute-defaults) for more information.* + +The attribute to retrieve which is shown on the Web UI to the user when they log in. + +### additional_groups_dn + +{{< confkey type="string" required="no" >}} + +Similar to [additional_users_dn](#additional_users_dn) but it applies to group searches. + +### groups_filter + +{{< confkey type="string" required="situational" >}} + +*__Note:__ This option is technically required however the [implementation](#implementation) option can implicitly set a +default negating this requirement. Refer to the [filter defaults](#filter-defaults) for more information.* + +Similar to [users_filter](#users_filter) but it applies to group searches. In order to include groups the member is not +a direct member of, but is a member of another group that is a member of those (i.e. recursive groups), you may try +using the following filter which is currently only tested against Microsoft Active Directory: + +`(&(member:1.2.840.113556.1.4.1941:={dn})(objectClass=group)(objectCategory=group))` + +## group_name_attribute + +{{< confkey type="string" required="situational" >}} + +*__Note:__ This option is technically required however the [implementation](#implementation) option can implicitly set a +default negating this requirement. Refer to the [attribute defaults](#attribute-defaults) for more +information.* + +The LDAP attribute that is used by Authelia to determine the group name. + +## permit_referrals + +{{< confkey type="boolean" default="false" required="no" >}} + +Permits following referrals. This is useful if you have read-only servers in your architecture and thus require +referrals to be followed when performing write operations. + +### user + +{{< confkey type="string" required="yes" >}} + +The distinguished name of the user paired with the password to bind with for lookup and password change operations. + +### password + +{{< confkey type="string" required="yes" >}} + +The password of the user paired with the user to bind with for lookup and password change operations. +Can also be defined using a [secret](../methods/secrets.md) which is the recommended for containerized deployments. + +## Implementation Guide + +There are currently two implementations, `custom` and `activedirectory`. The `activedirectory` implementation +must be used if you wish to allow users to change or reset their password as Active Directory +uses a custom attribute for this, and an input format other implementations do not use. The long term +intention of this is to have logical defaults for various RFC implementations of LDAP. + +### Filter replacements + +Various replacements occur in the user and groups filter. The replacements either occur at startup or upon an LDAP +search. + +#### Users filter replacements + +| Placeholder | Phase | Replacement | +|:------------------------:|:-------:|:-------------------------------------:| +| {username_attribute} | startup | The configured username attribute | +| {mail_attribute} | startup | The configured mail attribute | +| {display_name_attribute} | startup | The configured display name attribute | +| {input} | search | The input into the username field | + +#### Groups filter replacements + +| Placeholder | Phase | Replacement | +|:-----------:|:------:|:-------------------------------------------------------------------------:| +| {input} | search | The input into the username field | +| {username} | search | The username from the profile lookup obtained from the username attribute | +| {dn} | search | The distinguished name from the profile lookup | + +### Defaults + +The below tables describes the current attribute defaults for each implementation. + +#### Attribute defaults + +This table describes the attribute defaults for each implementation. i.e. the username_attribute is described by the +Username column. + +| Implementation | Username | Display Name | Mail | Group Name | +|:---------------:|:--------------:|:------------:|:----:|:----------:| +| custom | N/A | displayName | mail | cn | +| activedirectory | sAMAccountName | displayName | mail | cn | + +#### Filter defaults + +The filters are probably the most important part to get correct when setting up LDAP. You want to exclude disabled +accounts. The active directory example has two attribute filters that accomplish this as an example (more examples would +be appreciated). The userAccountControl filter checks that the account is not disabled and the pwdLastSet makes sure that +value is not 0 which means the password requires changing at the next login. + +| Implementation | Users Filter | Groups Filter | +|:---------------:|:---------------------------------------------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------:| +| custom | N/A | N/A | +| activedirectory | (&(|({username_attribute}={input})({mail_attribute}={input}))(sAMAccountType=805306368)(!(userAccountControl:1.2.840.113556.1.4.803:=2))(!(pwdLastSet=0))) | (&(member={dn})(objectClass=group)(objectCategory=group)) | + +*__Note:__* The Active Directory filter `(sAMAccountType=805306368)` is exactly the same as +`(&(objectCategory=person)(objectClass=user))` except that the former is more performant, you can read more about this +and other Active Directory filters on the [TechNet wiki](https://social.technet.microsoft.com/wiki/contents/articles/5392.active-directory-ldap-syntax-filters.aspx). + +## Refresh Interval + +It's recommended you either use the default [refresh interval](./introduction.md#refresh_interval) or configure this to +a value low enough to refresh the user groups and status (deleted, disabled, etc) to adequately secure your environment. + +## Important notes + +Users must be uniquely identified by an attribute, this attribute must obviously contain a single value and be guaranteed +by the administrator to be unique. If multiple users have the same value, Authelia will simply fail authenticating the +user and display an error message in the logs. + +In order to avoid such problems, we highly recommended you follow [RFC2307] by using `sAMAccountName` for Active +Directory and `uid` for other implementations as the attribute holding the unique identifier +for your users. + +[username attribute]: #username_attribute +[TechNet wiki]: https://social.technet.microsoft.com/wiki/contents/articles/5392.active-directory-ldap-syntax-filters.aspx +[RFC2307]: https://www.rfc-editor.org/rfc/rfc2307.html diff --git a/docs/content/en/configuration/identity-providers/_index.md b/docs/content/en/configuration/identity-providers/_index.md new file mode 100644 index 000000000..865b42b55 --- /dev/null +++ b/docs/content/en/configuration/identity-providers/_index.md @@ -0,0 +1,9 @@ +--- +title : "Identity Providers" +description: "Identity Providers Configuration" +lead: "" +date: 2022-03-20T12:52:27+11:00 +draft: false +images: [] +weight: 190000 +--- diff --git a/docs/content/en/configuration/identity-providers/introduction.md b/docs/content/en/configuration/identity-providers/introduction.md new file mode 100644 index 000000000..95b8d6109 --- /dev/null +++ b/docs/content/en/configuration/identity-providers/introduction.md @@ -0,0 +1,19 @@ +--- +title: "Identity Providers" +description: "Identity Providers Configuration" +lead: "Authelia is evolving to become an identity provider. This section describes how to configure this." +date: 2022-03-20T12:52:27+11:00 +draft: false +images: [] +menu: + configuration: + parent: "identity-providers" +weight: 190100 +toc: true +aliases: + - /docs/configuration/identity-providers/ +--- + +## OpenID Connect + +The only identity provider implementation supported at this time is [OpenID Connect](open-id-connect.md). diff --git a/docs/content/en/configuration/identity-providers/open-id-connect.md b/docs/content/en/configuration/identity-providers/open-id-connect.md new file mode 100644 index 000000000..a5afc342b --- /dev/null +++ b/docs/content/en/configuration/identity-providers/open-id-connect.md @@ -0,0 +1,406 @@ +--- +title: "OpenID Connect" +description: "OpenID Connect Configuration" +lead: "Authelia can operate as an OpenID Connect provider. This section describes how to configure this." +date: 2022-03-20T12:52:27+11:00 +draft: false +images: [] +menu: + configuration: + parent: "identity-providers" +weight: 190200 +toc: true +aliases: + - /c/oidc + - /docs/configuration/identity-providers/oidc.html +--- + +__Authelia__ currently supports the [OpenID Connect] OP role as a [__beta__](../../roadmap/active/openid-connect.md) +feature. The OP role is the [OpenID Connect] Provider role, not the Relying Party or RP role. This means other +applications that implement the [OpenID Connect] RP role can use Authelia as an authentication and authorization backend +similar to how you may use social media or development platforms for login. + +The Relying Party role is the role which allows an application to use GitHub, Google, or other [OpenID Connect] +providers for authentication and authorization. We do not intend to support this functionality at this moment in time. + +More information about the beta can be found in the [roadmap](../../roadmap/active/openid-connect.md). + +## Configuration + +The following snippet provides a sample-configuration for the OIDC identity provider explaining each field in detail. + +```yaml +identity_providers: + oidc: + hmac_secret: this_is_a_secret_abc123abc123abc + issuer_private_key: | + --- KEY START + --- KEY END + access_token_lifespan: 1h + authorize_code_lifespan: 1m + id_token_lifespan: 1h + refresh_token_lifespan: 90m + enable_client_debug_messages: false + enforce_pkce: public_clients_only + cors: + endpoints: + - authorization + - token + - revocation + - introspection + allowed_origins: + - https://example.com + allowed_origins_from_client_redirect_uris: false + clients: + - id: myapp + description: My Application + secret: this_is_a_secret + sector_identifier: '' + public: false + authorization_policy: two_factor + pre_configured_consent_duration: '' + audience: [] + scopes: + - openid + - groups + - email + - profile + redirect_uris: + - https://oidc.example.com:8080/oauth2/callback + grant_types: + - refresh_token + - authorization_code + response_types: + - code + response_modes: + - form_post + - query + - fragment + userinfo_signing_algorithm: none +``` + +## Options + +### hmac_secret + +{{< confkey type="string" required="yes" >}} + +The HMAC secret used to sign the [JWT]'s. The provided string is hashed to a SHA256 ([RFC6234]) byte string for the +purpose of meeting the required format. This secret must be generated by the administrator and can be done by following +the [Generating a Random Alphanumeric String](../miscellaneous/guides.md#generating-a-random-alphanumeric-string) guide. + +Should be defined using a [secret](../methods/secrets.md) which is the recommended for containerized deployments. + +### issuer_private_key + +{{< confkey type="string" required="yes" >}} + +The private key in DER base64 ([RFC4648]) encoded PEM format used to encrypt the [OpenID Connect] [JWT]'s. The key must +be generated by the administrator and can be done by following the +[Generating an RSA Keypair](../miscellaneous/guides.md#generating-an-rsa-keypair) guide. + +Should be defined using a [secret](../methods/secrets.md) which is the recommended for containerized deployments. + +### access_token_lifespan + +{{< confkey type="duration" default="1h" required="no" >}} + +The maximum lifetime of an access token. It's generally recommended keeping this short similar to the default. +For more information read these docs about [token lifespan]. + +### authorize_code_lifespan + +{{< confkey type="duration" default="1m" required="no" >}} + +The maximum lifetime of an authorize code. This can be rather short, as the authorize code should only be needed to +obtain the other token types. For more information read these docs about [token lifespan]. + +### id_token_lifespan + +{{< confkey type="duration" default="1h" required="no" >}} + +The maximum lifetime of an ID token. For more information read these docs about [token lifespan]. + +### refresh_token_lifespan + +{{< confkey type="string" default="90m" required="no" >}} + +The maximum lifetime of a refresh token. The +refresh token can be used to obtain new refresh tokens as well as access tokens or id tokens with an +up-to-date expiration. For more information read these docs about [token lifespan]. + +A good starting point is 50% more or 30 minutes more (which ever is less) time than the highest lifespan out of the +[access token lifespan](#access_token_lifespan), the [authorize code lifespan](#authorize_code_lifespan), and the +[id token lifespan](#id_token_lifespan). For instance the default for all of these is 60 minutes, so the default refresh +token lifespan is 90 minutes. + +### enable_client_debug_messages + +{{< confkey type="boolean" default="false" required="no" >}} + +Allows additional debug messages to be sent to the clients. + +### minimum_parameter_entropy + +{{< confkey type="integer" default="8" required="no" >}} + +This controls the minimum length of the `nonce` and `state` parameters. + +*__Security Notice:__* Changing this value is generally discouraged, reducing it from the default can theoretically +make certain scenarios less secure. It is highly encouraged that if your OpenID Connect RP does not send these +parameters or sends parameters with a lower length than the default that they implement a change rather than changing +this value. + +### enforce_pkce + +{{< confkey type="string" default="public_clients_only" required="no" >}} + +[Proof Key for Code Exchange](https://www.rfc-editor.org/rfc/rfc7636.html) enforcement policy: if specified, must be +either `never`, `public_clients_only` or `always`. + +If set to `public_clients_only` (default), [PKCE] will be required for public clients using the +[Authorization Code Flow]. + +When set to `always`, [PKCE] will be required for all clients using the Authorization Code flow. + +*__Security Notice:__* Changing this value to `never` is generally discouraged, reducing it from the default can +theoretically make certain client-side applications (mobile applications, SPA) vulnerable to CSRF and authorization code +interception attacks. + +### enable_pkce_plain_challenge + +{{< confkey type="boolean" default="false" required="no" >}} + +Allows [PKCE] `plain` challenges when set to `true`. + +*__Security Notice:__* Changing this value is generally discouraged. Applications should use the `S256` [PKCE] challenge +method instead. + +### cors + +Some [OpenID Connect] Endpoints need to allow cross-origin resource sharing, however some are optional. This section allows +you to configure the optional parts. We reply with CORS headers when the request includes the Origin header. + +#### endpoints + +{{< confkey type="list(string)" required="no" >}} + +A list of endpoints to configure with cross-origin resource sharing headers. It is recommended that the `userinfo` +option is at least in this list. The potential endpoints which this can be enabled on are as follows: + +* authorization +* token +* revocation +* introspection +* userinfo + +#### allowed_origins + +{{< confkey type="list(string)" required="no" >}} + +A list of permitted origins. + +Any origin with https is permitted unless this option is configured or the +[allowed_origins_from_client_redirect_uris](#allowed_origins_from_client_redirect_uris) option is enabled. This means +you must configure this option manually if you want http endpoints to be permitted to make cross-origin requests to the +[OpenID Connect] endpoints, however this is not recommended. + +Origins must only have the scheme, hostname and port, they may not have a trailing slash or path. + +In addition to an Origin URI, you may specify the wildcard origin in the allowed_origins. It MUST be specified by itself +and the [allowed_origins_from_client_redirect_uris](#allowed_origins_from_client_redirect_uris) MUST NOT be enabled. The +wildcard origin is denoted as `*`. Examples: + +```yaml +identity_providers: + oidc: + cors: + allowed_origins: "*" +``` + +```yaml +identity_providers: + oidc: + cors: + allowed_origins: + - "*" +``` + +#### allowed_origins_from_client_redirect_uris + +{{< confkey type="boolean" default="false" required="no" >}} + +Automatically adds the origin portion of all redirect URI's on all clients to the list of +[allowed_origins](#allowed_origins), provided they have the scheme http or https and do not have the hostname of +localhost. + +### clients + +{{< confkey type="list" required="yes" >}} + +A list of clients to configure. The options for each client are described below. + +#### id + +{{< confkey type="string" required="yes" >}} + +The Client ID for this client. It must exactly match the Client ID configured in the application +consuming this client. + +#### description + +{{< confkey type="string" default="*same as id*" required="no" >}} + +A friendly description for this client shown in the UI. This defaults to the same as the ID. + +#### secret + +{{< confkey type="string" required="situational" >}} + +The shared secret between Authelia and the application consuming this client. This secret must match the secret +configured in the application. Currently this is stored in plain text. + +This secret must be generated by the administrator and can be done by following the +[Generating a Random Alphanumeric String](../miscellaneous/guides.md#generating-a-random-alphanumeric-string) guide. + +This must be provided when the client is a confidential client type, and must be blank when using the public client +type. To set the client type to public see the [public](#public) configuration option. + +#### sector_identifier + +{{< confkey type="string" required="no" >}} + +*__Important Note:__ because adjusting this option will inevitably change the `sub` claim of all tokens generated for +the specified client, changing this should cause the relying party to detect all future authorizations as completely new +users.* + +Must be an empty string or the host component of a URL. This is commonly just the domain name, but may also include a +port. + +Authelia utilizes UUID version 4 subject identifiers. By default the public [Subject Identifier Type] is utilized for +all clients. This means the subject identifiers will be the same for all clients. This configuration option enables +[Pairwise Identifier Algorithm] for this client, and configures the sector identifier utilized for both the storage and +the lookup of the subject identifier. + +1. All clients who do not have this configured will generate the same subject identifier for a particular user + regardless of which client obtains the ID token. +2. All clients which have the same sector identifier will: + 1. have the same subject identifier for a particular user when compared to clients with the same sector identifier. + 2. have a completely different subject identifier for a particular user whe compared to: + 1. any client with the public subject identifier type. + 2. any client with a differing sector identifier. + +In specific but limited scenarios this option is beneficial for privacy reasons. In particular this is useful when the +party utilizing the *Authelia* [OpenID Connect] Authorization Server is foreign and not controlled by the user. It would +prevent the third party utilizing the subject identifier with another third party in order to track the user. + +Keep in mind depending on the other claims they may still be able to perform this tracking and it is not a silver +bullet. There are very few benefits when utilizing this in a homelab or business where no third party is utilizing +the server. + +#### public + +{{< confkey type="bool" default="false" required="no" >}} + +This enables the public client type for this client. This is for clients that are not capable of maintaining +confidentiality of credentials, you can read more about client types in [RFC6749 Section 2.1]. This is particularly +useful for SPA's and CLI tools. This option requires setting the [client secret](#secret) to a blank string. + +In addition to the standard rules for redirect URIs, public clients can use the `urn:ietf:wg:oauth:2.0:oob` redirect +URI. + +#### authorization_policy + +{{< confkey type="string" default="two_factor" required="no" >}} + +The authorization policy for this client: either `one_factor` or `two_factor`. + +#### pre_configured_consent_duration + +{{< confkey type="duration" required="no" >}} + +*__Note:__ This setting uses the [duration notation format](../prologue/common.md#duration-notation-format). Please see +the [common options](../prologue/common.md#duration-notation-format) documentation for information on this format.* + +Configuring this enables users of this client to remember their consent as a pre-configured consent. The period of time +dictates how long a users choice to remember the pre-configured consent lasts. + +Pre-configured consents are only valid if the subject, client id are exactly the same and the requested scopes/audience +match exactly with the granted scopes/audience. + +#### audience + +{{< confkey type="list(string)" required="no" >}} + +A list of audiences this client is allowed to request. + +#### scopes + +{{< confkey type="list(string)" default="openid, groups, profile, email" required="no" >}} + +A list of scopes to allow this client to consume. See +[scope definitions](../../integration/openid-connect/introduction.md#scope-definitions) for more information. The +documentation for the application you want to use with Authelia will most-likely provide you with the scopes to allow. + +#### redirect_uris + +{{< confkey type="list(string)" required="yes" >}} + +A list of valid callback URIs this client will redirect to. All other callbacks will be considered unsafe. The URIs are +case-sensitive and they differ from application to application - the community has provided +[a list of URL´s for common applications](../../integration/openid-connect/introduction.md). + +Some restrictions that have been placed on clients and +their redirect URIs are as follows: + +1. If a client attempts to authorize with Authelia and its redirect URI is not listed in the client configuration the + attempt to authorize wil fail and an error will be generated. +2. The redirect URIs are case-sensitive. +3. The URI must include a scheme and that scheme must be one of `http` or `https`. +4. The client can ignore rule 3 and use `urn:ietf:wg:oauth:2.0:oob` if it is a [public](#public) client type. + +#### grant_types + +{{< confkey type="list(string)" default="refresh_token, authorization_code" required="no" >}} + +A list of grant types this client can return. *It is recommended that this isn't configured at this time unless you +know what you're doing*. Valid options are: `implicit`, `refresh_token`, `authorization_code`, `password`, +`client_credentials`. + +#### response_types + +{{< confkey type="list(string)" default="code" required="no" >}} + +A list of response types this client can return. *It is recommended that this isn't configured at this time unless you +know what you're doing*. Valid options are: `code`, `code id_token`, `id_token`, `token id_token`, `token`, +`token id_token code`. + +#### response_modes + +{{< confkey type="list(string)" default="form_post, query, fragment" required="no" >}} + +A list of response modes this client can return. It is recommended that this isn't configured at this time unless you +know what you're doing. Potential values are `form_post`, `query`, and `fragment`. + +#### userinfo_signing_algorithm + +{{< confkey type="string" default="none" required="no" >}} + +The algorithm used to sign the userinfo endpoint responses. This can either be `none` or `RS256`. + +## Integration + +To integrate Authelia's [OpenID Connect] implementation with a relying party please see the +[integration docs](../../integration/openid-connect/introduction.md). + +[token lifespan]: https://docs.apigee.com/api-platform/antipatterns/oauth-long-expiration +[OpenID Connect]: https://openid.net/connect/ +[JWT]: https://www.rfc-editor.org/rfc/rfc7519.html +[RFC6234]: https://www.rfc-editor.org/rfc/rfc6234.html +[RFC4648]: https://www.rfc-editor.org/rfc/rfc4648.html +[RFC7468]: https://www.rfc-editor.org/rfc/rfc7468.html +[RFC6749 Section 2.1]: https://www.rfc-editor.org/rfc/rfc6749.html#section-2.1 +[PKCE]: https://www.rfc-editor.org/rfc/rfc7636.html +[Authorization Code Flow]: https://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth +[Subject Identifier Type]: https://openid.net/specs/openid-connect-core-1_0.html#SubjectIDTypes +[Pairwise Identifier Algorithm]: https://openid.net/specs/openid-connect-core-1_0.html#PairwiseAlg diff --git a/docs/content/en/configuration/methods/_index.md b/docs/content/en/configuration/methods/_index.md new file mode 100644 index 000000000..fd1fd0d0b --- /dev/null +++ b/docs/content/en/configuration/methods/_index.md @@ -0,0 +1,9 @@ +--- +title : "Methods" +description: "Methods of Configuration" +lead: "" +date: 2022-03-20T12:52:27+11:00 +draft: false +images: [] +weight: 101000 +--- diff --git a/docs/content/en/configuration/methods/environment.md b/docs/content/en/configuration/methods/environment.md new file mode 100644 index 000000000..15bdc7314 --- /dev/null +++ b/docs/content/en/configuration/methods/environment.md @@ -0,0 +1,51 @@ +--- +title: "Environment" +description: "Using the Environment Variable Configuration Method." +lead: "Authelia has a layered configuration model. This section describes how to implement the environment configuration." +date: 2022-03-20T12:52:27+11:00 +draft: false +images: [] +menu: + configuration: + parent: "methods" +weight: 101300 +toc: true +--- + +Environment variables are applied after the configuration file meaning anything specified as part of the environment +overrides the configuration files. + +*__Please Note:__ It is not possible to configure the access control rules section or OpenID Connect identity provider +clients section using environment variables at this time.* + +## Prefix + +The environment variables must be prefixed with `AUTHELIA_`. All environment variables that start with this prefix must +be for configuration. Any supplied environment variables that have this prefix and are not meant for configuration will +likely result in an error or even worse misconfiguration. + +### Kubernetes + +Please see the +[Kubernetes Integration: Enable Service Links](../../integration/kubernetes/introduction/index.md#enable-service-links) +documentation for specific requirements for using *Authelia* with Kubernetes. + +## Mapping + +Configuration options are mapped by their name. Levels of indentation / subkeys are replaced by underscores. + +For example this YAML configuration: + +```yaml +log: + level: info +server: + read_buffer_size: 4096 +``` + +Can be replaced by this environment variable configuration: + +```bash +AUTHELIA_LOG_LEVEL=info +AUTHELIA_SERVER_READ_BUFFER_SIZE=4096 +``` diff --git a/docs/content/en/configuration/methods/files.md b/docs/content/en/configuration/methods/files.md new file mode 100644 index 000000000..7e02b2bd5 --- /dev/null +++ b/docs/content/en/configuration/methods/files.md @@ -0,0 +1,112 @@ +--- +title: "Files" +description: "Using the YAML File Configuration Method." +lead: "Authelia can be configured via files. This section describes utilizing this method." +date: 2022-03-20T12:52:27+11:00 +draft: false +images: [] +menu: + configuration: + parent: "methods" +weight: 101200 +toc: true +--- + +*Authelia* loads `configuration.yml` as the configuration if you just run it. You can override this behaviour with the +following syntax: + +```bash +authelia --config config.custom.yml +``` + +## Multiple Configuration Files + +You can have multiple configuration files which will be merged in the order specified. If duplicate keys are specified +the last one to be specified is the one that takes precedence. Example: + +```bash +authelia --config configuration.yml --config config-acl.yml --config config-other.yml +authelia --config configuration.yml,config-acl.yml,config-other.yml +``` + +Authelia's configuration files use the YAML format. A template with all possible options can be found at the root of the +repository [here](https://github.com/authelia/authelia/blob/master/config.template.yml). + +*__Important Note:__ You should not have configuration sections such as Access Control Rules or OpenID Connect clients +configured in multiple files. If you wish to split these into their own files that is fine, but if you have two files that +specify these sections and expect them to merge properly you are asking for trouble.* + +### Container + +By default, the container looks for a configuration file at `/config/configuration.yml`. + +### Docker + +This is an example of how to override the configuration files loaded in docker: + +```bash +docker run -d --volume /path/to/config:/config authelia:authelia:latest authelia --config=/config/configuration.yaml --config=/config/configuration.acl.yaml +``` + +See the [Docker Documentation](https://docs.docker.com/engine/reference/commandline/run/) for more information on the +`docker run` command. + +### Docker Compose + +An excerpt from a docker compose that allows you to specify multiple configuration files is as follows: + +```yaml +version: "3.8" +services: + authelia: + container_name: authelia + image: authelia/authelia:latest + command: + - "authelia" + - "--config=/config/configuration.yaml" + - "--config=/config/configuration.acl.yaml" + +``` + +See the [compose file reference](https://docs.docker.com/compose/compose-file/compose-file-v3/#command) for more +information. + +### Kubernetes + +An excerpt from a Kubernetes container that allows you to specify multiple configuration files is as follows: + +```yaml +kind: Deployment +apiVersion: apps/v1 +metadata: + name: authelia + namespace: authelia + labels: + app.kubernetes.io/instance: authelia + app.kubernetes.io/name: authelia +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/instance: authelia + app.kubernetes.io/name: authelia + template: + metadata: + labels: + app.kubernetes.io/instance: authelia + app.kubernetes.io/name: authelia + spec: + enableServiceLinks: false + containers: + - name: authelia + image: docker.io/authelia/authelia:fix-missing-head-handler + command: + - authelia + args: + - '--config=/configuration.yaml' + - '--config=/configuration.acl.yaml' +``` + +See the Kubernetes [workloads documentation](https://kubernetes.io/docs/concepts/workloads/pods/#pod-templates) or the +[Container API docs](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#container-v1-core) for more +information. diff --git a/docs/content/en/configuration/methods/introduction.md b/docs/content/en/configuration/methods/introduction.md new file mode 100644 index 000000000..dc21fdc44 --- /dev/null +++ b/docs/content/en/configuration/methods/introduction.md @@ -0,0 +1,27 @@ +--- +title: "Methods" +description: "Methods of Configuration." +lead: "Authelia has a layered configuration model. This section describes how to implement configuration." +date: 2022-03-20T12:52:27+11:00 +draft: false +images: [] +menu: + configuration: + parent: "methods" +weight: 101100 +toc: true +--- + +## Layers + +Authelia has several methods of configuration available to it. The order of precedence is as follows: + +1. [Secrets](secrets.md) +2. [Environment Variables](environment.md) +3. [Files](files.md) (in order of them being specified) + +This order of precedence puts higher weight on things higher in the list. This means anything specified in the +[files](files.md) is overridden by [environment variables](environment.md) if specified, and anything specified by +[environment variables](environment.md) is overridden by [secrets](secrets.md) if specified. + +[YAML]: https://yaml.org/ diff --git a/docs/configuration/secrets.md b/docs/content/en/configuration/methods/secrets.md similarity index 82% rename from docs/configuration/secrets.md rename to docs/content/en/configuration/methods/secrets.md index d4510fe24..68996a211 100644 --- a/docs/configuration/secrets.md +++ b/docs/content/en/configuration/methods/secrets.md @@ -1,28 +1,52 @@ --- -layout: default -title: Secrets -parent: Configuration -nav_order: 11 +title: "Secrets" +description: "Using the Secrets Configuration Method." +lead: "Authelia allows providing configuration via secrets method. This section describes how to implement this." +date: 2022-03-20T12:52:27+11:00 +draft: false +images: [] +menu: + configuration: + parent: "methods" +weight: 101400 +toc: true +aliases: + - /c/secrets + - /docs/configuration/secrets.html --- -# Secrets +Configuration of *Authelia* requires several secrets and passwords. Even if they can be set in the configuration file or +standard environment variables, the recommended way to set secrets is to use this configuration method as described below. -Configuration of Authelia requires some secrets and passwords. Even if they can be set in the configuration file or -standard environment variables, the recommended way to set secrets is to use environment variables as described below. +See the [security](#security) section for more information. + +## Layers + +*__Important Note:__* While this method is the third layer of the layered configuration model as described by the +[introduction](introduction.md#layers), this layer is special in as much as *Authelia* will not start if you define +a secret as well as any other configuration method. + +For example if you define `jwt_secret` in the [files method](files.md) and/or `AUTHELIA_JWT_SECRET` in the +[environment method](environment.md), as well as the `AUTHELIA_JWT_SECRET_FILE`, this will cause the aforementioned error. + +## Security + +This method is a slight improvement over the security of the other methods as it allows you to easily separate your +configuration in a logically secure way. ## Environment variables -A secret value can be loaded by Authelia when the configuration key ends with one of the following words: `key`, -`secret`, `password`, or `token`. +A secret value can be loaded by *Authelia* when the configuration key ends with one of the following words: `key`, +`secret`, `password`, or `token`. If you take the expected environment variable for the configuration option with the `_FILE` suffix at the end. The value of these environment variables must be the path of a file that is readable by the Authelia process, if they are not, -Authelia will fail to load. Authelia will automatically remove the newlines from the end of the files contents. +*Authelia* will fail to load. Authelia will automatically remove the newlines from the end of the files contents. For instance the LDAP password can be defined in the configuration -at the path **authentication_backend.ldap.password**, so this password +at the path __authentication_backend.ldap.password__, so this password could alternatively be set using the environment variable called -**AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PASSWORD_FILE**. +__AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PASSWORD_FILE__. Here is the list of the environment variables which are considered secrets and can be defined. Please note that only secrets can be loaded into the configuration if they end with one of the suffixes above, you can set the value of any @@ -48,7 +72,7 @@ other configuration using the environment but instead of loading a file the valu If for some reason you decide on keeping the secrets in the configuration file, it is strongly recommended that you ensure the permissions of the configuration file are appropriately set so that other users or processes cannot access -this file. Generally the UNIX permissions that are appropriate are 0600. +this file. Generally the UNIX permissions that are appropriate are 0600. ## Secrets exposed in an environment variable @@ -57,9 +81,9 @@ setting the value to the value you wish to set in configuration, however we stro and instead use the file-based secrets above. Prior to implementing file secrets the only way you were able to define secret values was either via configuration or -via environment variables in plain text. +via environment variables in plain text. -See [this article](https://diogomonica.com/2017/03/27/why-you-shouldnt-use-env-variables-for-secret-data/) for reasons +See [this article](https://diogomonica.com/2017/03/27/why-you-shouldnt-use-env-variables-for-secret-data/) for reasons why setting them via the file counterparts is highly encouraged. ## Docker @@ -67,7 +91,6 @@ why setting them via the file counterparts is highly encouraged. Secrets can be provided in a `docker-compose.yml` either with Docker secrets or bind mounted secret files, examples of these are provided below. - ### Compose with Docker secrets This example assumes secrets are stored in `/path/to/authelia/secrets/{secretname}` @@ -179,7 +202,7 @@ metadata: data: duo_key: >- UXE1WmM4S0pldnl6eHRwQ3psTGpDbFplOXFueUVyWEZhYjE0Z01IRHN0RT0K - + jwt_secret: >- anotherBase64EncodedSecret @@ -189,7 +212,7 @@ data: where `UXE1WmM4S0pldnl6eHRwQ3psTGpDbFplOXFueUVyWEZhYjE0Z01IRHN0RT0K` is Base64 encoded for `Qq5Zc8KJevyzxtpCzlLjClZe9qnyErXFab14gMHDstE`, the actual content of the secret. You can generate these contents with -```sh +```console LENGTH=64 tr -cd '[:alnum:]' < /dev/urandom \ | fold -w "${LENGTH}" \ @@ -204,13 +227,11 @@ which writes the secret's content to the `actualSecretContent.txt` file and prin ### Kustomization -- **Filename:** ./kustomization.yaml -- **Command:** kubectl apply -k -- **Notes:** this kustomization expects the Authelia configuration.yml in - the same directory. You will need to edit the kustomization.yaml with your - desired secrets after the equal signs. If you change the value before the - equal sign you'll have to adjust the volumes section of the daemonset - template (or deployment template if you're using it). +* __Filename:__ ./kustomization.yaml +* __Command:__ kubectl apply -k +* __Notes:__ this kustomization expects the Authelia configuration.yml in the same directory. You will need to edit the + kustomization.yaml with your desired secrets after the equal signs. If you change the value before the equal sign + you'll have to adjust the volumes section of the daemonset template (or deployment template if you're using it). ```yaml #filename: ./kustomization.yaml @@ -237,9 +258,10 @@ secretGenerator: ### DaemonSet -- **Filename:** ./daemonset.yaml -- **Command:** kubectl apply -f ./daemonset.yaml -- **Notes:** assumes Kubernetes API 1.16 or greater +* __Filename:__ ./daemonset.yaml +* __Command:__ kubectl apply -f ./daemonset.yaml +* __Notes:__ assumes Kubernetes API 1.16 or greater + ```yaml #filename: daemonset.yaml #command: kubectl apply -f daemonset.yaml diff --git a/docs/content/en/configuration/miscellaneous/_index.md b/docs/content/en/configuration/miscellaneous/_index.md new file mode 100644 index 000000000..9ff036894 --- /dev/null +++ b/docs/content/en/configuration/miscellaneous/_index.md @@ -0,0 +1,9 @@ +--- +title : "Miscellaneous" +description: "Miscellaneous Configuration" +lead: "" +date: 2022-03-20T12:52:27+11:00 +draft: false +images: [] +weight: 199000 +--- diff --git a/docs/content/en/configuration/miscellaneous/guides.md b/docs/content/en/configuration/miscellaneous/guides.md new file mode 100644 index 000000000..64b5a4023 --- /dev/null +++ b/docs/content/en/configuration/miscellaneous/guides.md @@ -0,0 +1,77 @@ +--- +title: "Guides" +description: "Miscellaneous Guides for Configuration." +lead: "This section contains miscellaneous guides used in the configuration." +date: 2022-05-16T15:21:22+10:00 +draft: false +images: [] +menu: + configuration: + parent: "miscellaneous" +weight: 199500 +toc: true +--- + +## Generating a Random Alphanumeric String + +Some sections of the configuration recommend generating a random string. There are many ways to accomplish this, one +possible way on Linux is utilizing the following command which prints a string with a length in characters of +`${LENGTH}` to `stdout`. The string will only contain alphanumeric characters. + +```bash +LENGTH=64 +tr -cd '[:alnum:]' < /dev/urandom | fold -w "${LENGTH}" | head -n 1 | tr -d '\n' ; echo +``` + +## Generating an RSA Keypair + +Some sections of the configuration need an RSA keypair. There are many ways to achieve this, this section explains two +such ways. + +### openssl + +The `openssl` command on Linux can be used to generate a RSA 4096 bit keypair: + +```bash +openssl genrsa -out private.pem 4096 +openssl rsa -in private.pem -outform PEM -pubout -out public.pem +``` + +### authelia + +The __Authelia__ docker container or CLI binary can be used to generate a RSA 4096 bit keypair: + +```bash +docker run -u "$(id -u):$(id -g)" -v "$(pwd)":/keys authelia/authelia:latest authelia rsa generate --dir /keys +``` + +```bash +authelia rsa generate --dir /path/to/keys +``` + +## Generating an RSA Self-Signed Certificate + +Some sections of the configuration need a certificate and it may be possible to use a self-signed certificate. There are +many ways to achieve this, this section explains two such ways. + +### openssl + +The `openssl` command on Linux can be used to generate a RSA 4096 bit self-signed certificate for the domain +`example.com`: + +```bash +openssl req -x509 -nodes -newkey rsa:4096 -keyout key.pem -out cert.pem -sha256 -days 365 -subj '/CN=example.com' +``` + +### authelia + +The __Authelia__ docker container or binary can be used to generate a RSA 4096 bit self-signed certificate for the +domain `example.com`: + +```bash +docker run -u "$(id -u):$(id -g)" -v "$(pwd)":/keys authelia/authelia authelia certificates generate --host example.com --dir /keys +``` + +```bash +authelia certificates generate --host example.com --dir /path/to/keys +``` diff --git a/docs/configuration/miscellaneous.md b/docs/content/en/configuration/miscellaneous/introduction.md similarity index 59% rename from docs/configuration/miscellaneous.md rename to docs/content/en/configuration/miscellaneous/introduction.md index 137ebaf36..ff572b3f3 100644 --- a/docs/configuration/miscellaneous.md +++ b/docs/content/en/configuration/miscellaneous/introduction.md @@ -1,51 +1,41 @@ --- -layout: default -title: Miscellaneous -parent: Configuration -nav_order: 7 +title: "Miscellaneous" +description: "Miscellaneous Configuration." +lead: "Authelia has a few config items that don't fit into their own area. This describes these options." +date: 2022-03-20T12:52:27+11:00 +draft: false +images: [] +menu: + configuration: + parent: "miscellaneous" +weight: 199100 +toc: true +aliases: + - /docs/configuration/miscellaneous.html + - /docs/configuration/theme.html --- -# Miscellaneous +## Configuration -Here are the main customizable options in Authelia that don't fit into their own sections. +```yaml +certificates_directory: /config/certs/ +default_redirection_url: https://home.example.com:8080/ +jwt_secret: v3ry_important_s3cr3t +theme: light +``` -## certificates_directory +## Options + +### certificates_directory This option defines the location of additional certificates to load into the trust chain specifically for Authelia. This currently affects both the SMTP notifier and the LDAP authentication backend. The certificates should all be in the PEM format and end with the extension `.pem`, `.crt`, or `.cer`. You can either add the individual certificates public key or the CA public key which signed them (don't add the private key). -```yaml -certificates_directory: /config/certs/ -``` +### default_redirection_url -## jwt_secret -
-type: string -{: .label .label-config .label-purple } -default: "" -{: .label .label-config .label-blue } -required: yes -{: .label .label-config .label-red } -
- -Defines the secret used to craft JWT tokens leveraged by the identity -verification process. This can also be defined using a [secret](./secrets.md). - -```yaml -jwt_secret: v3ry_important_s3cr3t -``` - -## default_redirection_url -
-type: string -{: .label .label-config .label-purple } -default: "" -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
+{{< confkey type="string" required="no" >}} The default redirection URL is the URL where users are redirected when Authelia cannot detect the target URL where the user was heading. @@ -56,19 +46,9 @@ can redirect them after the authentication process. However, when a user visits considers the targeted website is the portal. In that case and if the default redirection URL is configured, the user is redirected to that URL. If not defined, the user is not redirected after authentication. -```yaml -default_redirection_url: https://home.example.com:8080/ -``` +### default_2fa_method -## default_2fa_method -
-type: string -{: .label .label-config .label-purple } -default: "" -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
+{{< confkey type="string" default="totp" required="no" >}} Sets the default second factor method for users. This must be blank or one of the enabled methods. New users will by default have this method selected for them. In addition if this was configured to `webauthn` and a user had the `totp` @@ -77,10 +57,32 @@ method, and the `totp` method was disabled in the configuration, the users' meth Options are: -- totp -- webauthn -- mobile_push +* totp +* webauthn +* mobile_push ```yaml default_2fa_method: totp -``` \ No newline at end of file +``` + +### jwt_secret + +{{< confkey type="string" required="yes" >}} + +Defines the secret used to craft JWT tokens leveraged by the identity +verification process. This can also be defined using a [secret](../methods/secrets.md). + +### theme + +{{< confkey type="string " default="light" required="no" >}} + +There are currently 3 available themes for Authelia: + +* light (default) +* dark +* grey + +To enable automatic switching between themes, you can set `theme` to `auto`. The theme will be set to either `dark` or +`light` depending on the user's system preference which is determined using media queries. To read more technical +details about the media queries used, read the +[MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme). diff --git a/docs/configuration/logging.md b/docs/content/en/configuration/miscellaneous/logging.md similarity index 67% rename from docs/configuration/logging.md rename to docs/content/en/configuration/miscellaneous/logging.md index b0b5a95bf..c46bec794 100644 --- a/docs/configuration/logging.md +++ b/docs/content/en/configuration/miscellaneous/logging.md @@ -1,12 +1,19 @@ --- -layout: default -title: Logging -parent: Configuration -nav_order: 5 +title: "Log" +description: "Configuring the Log Settings." +lead: "Authelia performs logging to various locations. This section describes how to configure and tune this." +date: 2022-03-20T12:52:27+11:00 +draft: false +images: [] +menu: + configuration: + parent: "miscellaneous" +weight: 199400 +toc: true +aliases: + - /docs/configuration/logging.html --- -# Logging - The logging section tunes the logging settings. ## Configuration @@ -22,14 +29,8 @@ log: ## Options ### level -
-type: string -{: .label .label-config .label-purple } -default: info -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
+ +{{< confkey type="string" default="info" required="no" >}} Defines the level of logs used by Authelia. This level can be set to `trace`, `debug`, `info`, `warn`, or `error`. When setting level to `trace`, you will generate a large amount of log entries and expose the `/debug/vars` and @@ -41,14 +42,8 @@ log: ``` ### format -
-type: string -{: .label .label-config .label-purple } -default: text -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
+ +{{< confkey type="string" default="text" required="no" >}} Defines the format of the logs written by Authelia. This format can be set to `json` or `text`. @@ -58,39 +53,40 @@ log: ``` #### JSON format -``` + +```json {"level":"info","msg":"Logging severity set to info","time":"2020-01-01T00:00:00+11:00"} {"level":"info","msg":"Authelia is listening for non-TLS connections on 0.0.0.0:9091","time":"2020-01-01T00:00:00+11:00"} ``` + #### Text format -``` + +```text time="2020-01-01T00:00:00+11:00" level=info msg="Logging severity set to info" time="2020-01-01T00:00:00+11:00" level=info msg="Authelia is listening for non-TLS connections on 0.0.0.0:9091" ``` ### file_path -
-type: string (path) -{: .label .label-config .label-purple } -default: "" -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
+ +{{< confkey type="string" required="no" >}} Logs can be stored in a file when file path is provided. Otherwise logs are written to standard output. When setting the level to `debug` or `trace` this will generate large amount of log entries. Administrators will need to ensure that they rotate and/or truncate the logs over time to prevent significant long-term disk usage. +If you include the value `%d` in the filename it will replace this value with a date time indicative of the time +the logger was initialized using `2006-02-01T150405Z` as the format. + +#### File Path Examples + +__Standard Example:__ + ```yaml log: file_path: /config/authelia.log ``` -If you include the value `%d` in the filename it will replace this value with a date time indicative of the time -the logger was initialized in the following format: - -`2006-02-01T150405Z` +__Date Time Example:__ ```yaml log: @@ -98,14 +94,8 @@ log: ``` ### keep_stdout -
-type: boolean -{: .label .label-config .label-purple } -default: false -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
+ +{{< confkey type="boolean" default="false" required="no" >}} Overrides the behaviour to redirect logging only to the `file_path`. If set to `true` logs will be written to both standard output, and the defined logging location. @@ -113,4 +103,4 @@ standard output, and the defined logging location. ```yaml log: keep_stdout: true -``` \ No newline at end of file +``` diff --git a/docs/content/en/configuration/miscellaneous/ntp.md b/docs/content/en/configuration/miscellaneous/ntp.md new file mode 100644 index 000000000..a8c50cbb0 --- /dev/null +++ b/docs/content/en/configuration/miscellaneous/ntp.md @@ -0,0 +1,70 @@ +--- +title: "NTP" +description: "Configuring the NTP Settings." +lead: "Authelia checks the system time is in sync with an NTP server. This section describes how to configure and tune this." +date: 2022-03-20T12:52:27+11:00 +draft: false +images: [] +menu: + configuration: + parent: "miscellaneous" +weight: 199300 +toc: true +aliases: + - /docs/configuration/ntp.html +--- + +Authelia has the ability to check the system time against an NTP server. Currently this only occurs at startup. This +section configures and tunes the settings for this check which is primarily used to ensure +[TOTP](../second-factor/time-based-one-time-password.md) can be accurately validated. + +In the instance of inability to contact the NTP server Authelia will just log an error and will continue to run. + +## Configuration + +```yaml +ntp: + address: "time.cloudflare.com:123" + version: 3 + max_desync: 3s + disable_startup_check: false + disable_failure: false +``` + +## Options + +### address + +{{< confkey type="string" default="time.cloudflare.com:123" required="no" >}} + +Determines the address of the NTP server to retrieve the time from. The format is `:`, and both of these are +required. + +### version + +{{< confkey type="integer" default="4" required="no" >}} + +Determines the NTP version supported. Valid values are 3 or 4. + +### max_desync + +{{< confkey type="duration" default="3s" required="no" >}} + +*__Note:__ This setting uses the [duration notation format](../prologue/common.md#duration-notation-format). Please see +the [common options](../prologue/common.md#duration-notation-format) documentation for information on this format.* + +This is used to tune the acceptable desync from the time reported from the NTP server. + +### disable_startup_check + +{{< confkey type="boolean" default="false" required="no" >}} + +Setting this to true will disable the startup check entirely. + +### disable_failure + +{{< confkey type="boolean" default="false" required="no" >}} + +Setting this to true will allow Authelia to start and just log an error instead of exiting. The default is that if +Authelia can contact the NTP server successfully, and the time reported by the server is greater than what is configured +in [max_desync](#max_desync) that Authelia fails to start and logs a fatal error. diff --git a/docs/content/en/configuration/miscellaneous/server.md b/docs/content/en/configuration/miscellaneous/server.md new file mode 100644 index 000000000..c49bda594 --- /dev/null +++ b/docs/content/en/configuration/miscellaneous/server.md @@ -0,0 +1,188 @@ +--- +title: "Server" +description: "Configuring the Server Settings." +lead: "Authelia runs an internal webserver. This section describes how to configure and tune this." +date: 2022-03-20T12:52:27+11:00 +draft: false +images: [] +menu: + configuration: + parent: "miscellaneous" +weight: 199200 +toc: true +aliases: + - /c/server + - /docs/configuration/server.html +--- + +## Configuration + +```yaml +server: + host: 0.0.0.0 + port: 9091 + path: "" + read_buffer_size: 4096 + write_buffer_size: 4096 + enable_pprof: false + enable_expvars: false + disable_healthcheck: false + tls: + key: "" + certificate: "" + client_certificates: [] + headers: + csp_template: "" +``` + +## Options + +## host + +{{< confkey type="string" default="0.0.0.0" required="no" >}} + +Defines the address to listen on. See also [port](#port). Should typically be `0.0.0.0` or `127.0.0.1`, the former for +containerized environments and the later for daemonized environments like init.d and systemd. + +Note: If utilising an IPv6 literal address it must be enclosed by square brackets and quoted: + +```yaml +host: "[fd00:1111:2222:3333::1]" +``` + +### port + +{{< confkey type="integer" default="9091" required="no" >}} + +Defines the port to listen on. See also [host](#host). + +### path + +{{< confkey type="string " required="no" >}} + +Authelia by default is served from the root `/` location, either via its own domain or subdomain. + +Modifying this setting will allow you to serve Authelia out from a specified base path. Please note +that currently only a single level path is supported meaning slashes are not allowed, and only +alphanumeric characters are supported. + +__Example:__ + +```yaml +server: + path: "" +``` + +*Works for https://auth.example.com/, https://example.com/, etc*. + +__Example:__ + +```yaml +server: + path: authelia +``` + +*Works for https://auth.example.com/authelia/, https://example.com/authelia/, etc*. + +### asset_path + +{{< confkey type="string " required="no" >}} + +Authelia by default serves all static assets from an embedded filesystem in the Go binary. + +Modifying this setting will allow you to override and serve specific assets for Authelia from a specified path. All +assets that can be overridden must be placed in the `asset_path`. The structure of this directory and the assets which +can be overriden is documented in the +[Sever Asset Overrides Reference Guide](../../reference/guides/server-asset-overrides.md). + +### read_buffer_size + +{{< confkey type="integer " default="4096" required="no" >}} + +Configures the maximum request size. The default of 4096 is generally sufficient for most use cases. + +### write_buffer_size + +{{< confkey type="integer " default="4096" required="no" >}} + +Configures the maximum response size. The default of 4096 is generally sufficient for most use cases. + +### enable_pprof + +{{< confkey type="boolean" default="false" required="no" >}} + +Enables the go pprof endpoints. + +### enable_expvars + +{{< confkey type="boolean" default="false" required="no" >}} + +Enables the go expvars endpoints. + +### disable_healthcheck + +{{< confkey type="boolean" default="false" required="no" >}} + +On startup Authelia checks for the existence of /app/healthcheck.sh and /app/.healthcheck.env and if both of these exist +it writes the configuration vars for the healthcheck to the /app/.healthcheck.env file. In instances where this is not +desirable it's possible to disable these interactions entirely. + +An example situation where this is the case is in Kubernetes when set security policies that prevent writing to the +ephemeral storage of a container or just don't want to enable the internal health check. + +### tls + +Authelia typically listens for plain unencrypted connections. This is by design as most environments allow to +security on lower areas of the OSI model. However it required, if you specify both the [tls key](#key) and +[tls certificate](#certificate) options, Authelia will listen for TLS connections. + +The key must be generated by the administrator and can be done by following the +[Generating an RSA Self Signed Certificate](../miscellaneous/guides.md#generating-an-rsa-self-signed-certificate) +guide provided a self-signed certificate is fit for purpose. If a self-signed certificate is fit for purpose is beyond +the scope of the documentation and if it is not fit for purpose we instead recommend generating a certificate signing +request or obtaining a certificate signed by one of the many ACME certificate providers. Methods to achieve this are +beyond the scope of this guide. + +#### key + +{{< confkey type="string" required="situational" >}} + +The path to the private key for TLS connections. Must be in DER base64/PEM format. + +#### certificate + +{{< confkey type="string" required="situational" >}} + +The path to the public certificate for TLS connections. Must be in DER base64/PEM format. + +#### client_certificates + +{{< confkey type="list(string)" required="situational" >}} + +The list of file paths to certificates used for authenticating clients. Those certificates can be root +or intermediate certificates. If no item is provided mutual TLS is disabled. + +### headers + +#### csp_template + +{{< confkey type="string" required="no" >}} + +This customizes the value of the Content-Security-Policy header. It will replace all instances of `${NONCE}` with the +nonce value of the Authelia react bundle. This is an advanced option to customize and you should do sufficient research +about how browsers utilize and understand this header before attempting to customize it. + +For example, the default CSP template is `default-src 'self'; object-src 'none'; style-src 'self' 'nonce-${NONCE}'`. + +## Additional Notes + +### Buffer Sizes + +The read and write buffer sizes generally should be the same. This is because when Authelia verifies +if the user is authorized to visit a URL, it also sends back nearly the same size response as the request. However +you're able to tune these individually depending on your needs. + +### Asset Overrides + +If replacing the Logo for your Authelia portal it is recommended to upload a transparent PNG of your desired logo. +Authelia will automatically resize the logo to an appropriate size to present in the frontend. diff --git a/docs/content/en/configuration/notifications/_index.md b/docs/content/en/configuration/notifications/_index.md new file mode 100644 index 000000000..a65ea9b99 --- /dev/null +++ b/docs/content/en/configuration/notifications/_index.md @@ -0,0 +1,9 @@ +--- +title : "Notifications" +description: "Notifiations Configuration" +lead: "" +date: 2022-03-20T12:52:27+11:00 +draft: false +images: [] +weight: 107000 +--- diff --git a/docs/content/en/configuration/notifications/file.md b/docs/content/en/configuration/notifications/file.md new file mode 100644 index 000000000..2e720c0f2 --- /dev/null +++ b/docs/content/en/configuration/notifications/file.md @@ -0,0 +1,37 @@ +--- +title: "File System" +description: "Configuring the File Notifications Settings." +lead: "Authelia can save notifications to a file. This section describes how to configure this." +date: 2022-03-20T12:52:27+11:00 +draft: false +images: [] +menu: + configuration: + parent: "notifications" +weight: 107300 +toc: true +aliases: + - /docs/configuration/notifier/filesystem.html +--- + +It is recommended in a production environment that you do not use the file notification system, and that it should only +be used for testing purposes. See one of [the other methods](introduction.md) for a production ready solution. + +This method will use the plain text email template for readability purposes. + +## Configuration + +```yaml +notifier: + disable_startup_check: false + filesystem: + filename: /config/notification.txt +``` + +## Options + +### filename + +{{< confkey type="string" required="yes" >}} + +The file to add email text to. If it doesn't exist it will be created. diff --git a/docs/content/en/configuration/notifications/introduction.md b/docs/content/en/configuration/notifications/introduction.md new file mode 100644 index 000000000..3eea1ce15 --- /dev/null +++ b/docs/content/en/configuration/notifications/introduction.md @@ -0,0 +1,53 @@ +--- +title: "Notifications" +description: "Configuring the Notifications Settings." +lead: "Authelia sends messages to users in order to verify their identity. This section describes how to configure this." +date: 2022-03-20T12:52:27+11:00 +draft: false +images: [] +menu: + configuration: + parent: "notifications" +weight: 107100 +toc: true +--- + +Authelia sends messages to users in order to verify their identity. + +## Configuration + +```yaml +notifier: + disable_startup_check: false + template_path: '' + filesystem: {} + smtp: {} +``` + +## Options + +### disable_startup_check + +{{< confkey type="boolean" default="false" required="no" >}} + +The notifier has a startup check which validates the specified provider configuration is correct and will be able to +send emails. This can be disabled with the `disable_startup_check` option. + +### template_path + +{{< confkey type="string" required="no" >}} + +*__Note:__ you may configure this directory and add only add the templates you wish to override, any templates not +supplied in this folder will utilize the default templates.* + +This option allows the administrator to set a path to a directory where custom templates for notifications can be found. +The specifics are located in the +[Notification Templates Reference Guide](../../reference/guides/notification-templates.md). + +### filesystem + +The [filesystem](file.md) provider. + +### smtp + +The [smtp](smtp.md) provider. diff --git a/docs/configuration/notifier/smtp.md b/docs/content/en/configuration/notifications/smtp.md similarity index 52% rename from docs/configuration/notifier/smtp.md rename to docs/content/en/configuration/notifications/smtp.md index 706904586..8c5231fd9 100644 --- a/docs/configuration/notifier/smtp.md +++ b/docs/content/en/configuration/notifications/smtp.md @@ -1,14 +1,19 @@ --- -layout: default -title: SMTP -parent: Notifier -grand_parent: Configuration -nav_order: 2 +title: "SMTP" +description: "Configuring the SMTP Notifications Settings." +lead: "Authelia can send emails to users through an SMTP server. This section describes how to configure this." +date: 2022-03-20T12:52:27+11:00 +draft: false +images: [] +menu: + configuration: + parent: "notifications" +weight: 107200 +toc: true +aliases: + - /docs/configuration/notifier/smtp.html --- -# SMTP -**Authelia** can send emails to users through an SMTP server. -It can be configured as described below. ## Configuration @@ -36,12 +41,8 @@ notifier: ## Options ### host -
-type: integer -{: .label .label-config .label-purple } -required: yes -{: .label .label-config .label-red } -
+ +{{< confkey type="integer" required="yes" >}} The hostname of the SMTP server. @@ -53,145 +54,97 @@ host: "[fd00:1111:2222:3333::1]" ### port -
-type: integer -{: .label .label-config .label-purple } -required: yes -{: .label .label-config .label-red } -
+{{< confkey type="integer" required="yes" >}} The port the SMTP service is listening on. ### timeout -
-type: duration -{: .label .label-config .label-purple } -default: 5s -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
+ +{{< confkey type="duration" default="5s" required="no" >}} The SMTP connection timeout. ### username -
-type: string -{: .label .label-config .label-purple } -required: no -{: .label .label-config .label-green } -
+ +{{< confkey type="string" required="no" >}} The username sent for authentication with the SMTP server. Paired with the password. ### password -
-type: string -{: .label .label-config .label-purple } -required: no -{: .label .label-config .label-green } -
+ +{{< confkey type="string" required="no" >}} The password sent for authentication with the SMTP server. Paired with the username. Can also be defined using a -[secret](../secrets.md) which is the recommended for containerized deployments. +[secret](../methods/secrets.md) which is the recommended for containerized deployments. + +We recommend generating a random string with 64 characters or more for this purposes which can be done by following the +[Generating a Random Alphanumeric String](../miscellaneous/guides.md#generating-a-random-alphanumeric-string) +guide. ### sender -
-type: string -{: .label .label-config .label-purple } -required: yes -{: .label .label-config .label-red } -
+ +{{< confkey type="string" required="yes" >}} The sender is used to construct both the SMTP command `MAIL FROM` and to add the `FROM` header. This address must be -in [RFC5322](https://datatracker.ietf.org/doc/html/rfc5322#section-3.4) format. This means it must one of two formats: -- jsmith@domain.com -- John Smith +in [RFC5322](https://www.rfc-editor.org/rfc/rfc5322.html#section-3.4) format. This means it must one of two formats: + +* jsmith@domain.com +* John Smith The `MAIL FROM` command sent to SMTP servers will not include the name portion, this is only set in the `FROM` as per specifications. ### identifier -
-type: string -{: .label .label-config .label-purple } -default: localhost -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
+ +{{< confkey type="string" default="localhost" required="no" >}} The name to send to the SMTP server as the identifier with the HELO/EHLO command. Some SMTP providers like Google Mail reject the message if it's localhost. ### subject -
-type: string -{: .label .label-config .label-purple } -default: [Authelia] {title} -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
+ +{{< confkey type="string" default="[Authelia] {title}" required="no" >}} This is the subject Authelia will use in the email, it has a single placeholder at present `{title}` which should be included in all emails as it is the internal descriptor for the contents of the email. ### startup_check_address -
-type: string -{: .label .label-config .label-purple } -default: test@authelia.com -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
-**Authelia** checks the SMTP server is valid at startup, one of the checks requires we ask the SMTP server if it can +{{< confkey type="string" default="test@authelia.com" required="no" >}} + +__Authelia__ checks the SMTP server is valid at startup, one of the checks requires we ask the SMTP server if it can send an email from us to a specific address, this is that address. No email is actually sent in the process. It is fine to leave this as is, but you can customize it if you have issues or you desire to. ### disable_require_tls -
-type: boolean -{: .label .label-config .label-purple } -default: false -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
+ +{{< confkey type="boolean" default="false" required="no" >}} For security reasons the default settings for Authelia require the SMTP connection is encrypted by TLS. See [security] for more information. This option disables this measure (not recommended). ### disable_html_emails -
-type: boolean -{: .label .label-config .label-purple } -default: false -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
-This setting completely disables HTML formatting of emails and only sends text emails. **Authelia** by default sends +{{< confkey type="boolean" default="false" required="no" >}} + +This setting completely disables HTML formatting of emails and only sends text emails. __Authelia__ by default sends mixed emails which contain both HTML and text so this option is rarely necessary. ### tls Controls the TLS connection validation process. You can see how to configure the tls section -[here](../index.md#tls-configuration). - +[here](../prologue/common.md#tls-configuration). ## Using Gmail -You need to generate an app password in order to use Gmail SMTP servers. The process is -described [here](https://support.google.com/accounts/answer/185833?hl=en) + +You need to generate an app password in order to use Gmail SMTP servers. The process is described +[here](https://support.google.com/accounts/answer/185833?hl=en). ```yaml notifier: smtp: username: myaccount@gmail.com - # Password can also be set using a secret: https://www.authelia.com/docs/configuration/secrets.html + # Password can also be set using a secret: https://www.authelia.com/configuration/methods/secrets/ password: yourapppassword sender: admin@example.com host: smtp.gmail.com diff --git a/docs/content/en/configuration/prologue/_index.md b/docs/content/en/configuration/prologue/_index.md new file mode 100644 index 000000000..7ed72af88 --- /dev/null +++ b/docs/content/en/configuration/prologue/_index.md @@ -0,0 +1,9 @@ +--- +title : "Prologue" +description: "Configuration Prologue" +lead: "" +date: 2022-03-20T12:52:27+11:00 +draft: false +images: [] +weight: 100000 +--- diff --git a/docs/content/en/configuration/prologue/common.md b/docs/content/en/configuration/prologue/common.md new file mode 100644 index 000000000..43d28a8bf --- /dev/null +++ b/docs/content/en/configuration/prologue/common.md @@ -0,0 +1,109 @@ +--- +title: "Common" +description: "Common configuration options and notations." +lead: "This section details common configuration elements within the Authelia configuration. This section is mainly used as a reference for other sections as necessary." +date: 2022-03-20T12:52:27+11:00 +draft: false +images: [] +menu: + configuration: + parent: "prologue" +weight: 100200 +toc: true +aliases: + - /c/common +--- + +## Duration Notation Format + +We have implemented a string/integer based notation for configuration options that take a duration of time. This section +describes the implementation of this. You can use this implementation in various areas of configuration such as: + +* session: + * expiration + * inactivity + * remember_me_duration +* regulation: + * ban_time + * find_time +* ntp: + * max_desync +* webauthn: + * timeout + +The way this format works is you can either configure an integer or a string in the specific configuration areas. If you +supply an integer, it is considered a representation of seconds. If you supply a string, it parses the string in blocks +of quantities and units (number followed by a unit letter). For example `5h` indicates a quantity of 5 units of `h`. + +While you can use multiple of these blocks in combination, ee suggest keeping it simple and use a single value. + +### Unit Legend + +| Unit | Associated Letter | +|:-------:|:-----------------:| +| Years | y | +| Months | M | +| Weeks | w | +| Days | d | +| Hours | h | +| Minutes | m | +| Seconds | s | + +### Examples + +| Desired Value | Configuration Examples | +|:---------------------:|:-------------------------------------:| +| 1 hour and 30 minutes | `90m` or `1h30m` or `5400` or `5400s` | +| 1 day | `1d` or `24h` or `86400` or `86400s` | +| 10 hours | `10h` or `600m` or `9h60m` or `36000` | + +## Regular Expressions + +We have several sections of configuration that utilize regular expressions. It's recommended to validate your regex +manually either via tools like [Regex 101](https://regex101.com/) (ensure you pick the `Golang` option) or some other +means. + +It's important when attempting to utilize a backslash that it's utilized correctly. The YAML parser is likely to parse +this as you trying to use YAML escape syntax instead of regex escape syntax. To avoid this use single quotes instead of +no quotes or double quotes. + +Good Example: + +```yaml +domain_regex: '^(admin|secure)\.example\.com$' +``` + +Bad Example: + +```yaml +domain_regex: "^(admin|secure)\.example\.com$" +``` + +## TLS Configuration + +Various sections of the configuration use a uniform configuration section called TLS. Notably LDAP and SMTP. +This section documents the usage. + +### server_name + +{{< confkey type="string" required="no" >}} + +The key `server_name` overrides the name checked against the certificate in the verification process. Useful if you +require to use a direct IP address for the address of the backend service but want to verify a specific SNI. + +### skip_verify + +{{< confkey type="boolean" default="false" required="no" >}} + +The key `skip_verify` completely negates validating the certificate of the backend service. This is not recommended, +instead you should tweak the `server_name` option, and the global option +[certificates directory](../miscellaneous/introduction.md#certificates_directory). + +### minimum_version + +{{< confkey type="string" default="TLS1.2" required="no" >}} + +The key `minimum_version` controls the minimum TLS version Authelia will use when opening TLS connections. +The possible values are `TLS1.3`, `TLS1.2`, `TLS1.1`, `TLS1.0`. Anything other than `TLS1.3` or `TLS1.2` +are very old and deprecated. You should avoid using these and upgrade your backend service instead of decreasing +this value. diff --git a/docs/content/en/configuration/prologue/introduction.md b/docs/content/en/configuration/prologue/introduction.md new file mode 100644 index 000000000..7a19ef039 --- /dev/null +++ b/docs/content/en/configuration/prologue/introduction.md @@ -0,0 +1,48 @@ +--- +title: "Prologue" +description: "An introduction into configuring Authelia." +lead: "An introduction into configuring Authelia." +date: 2022-03-20T12:52:27+11:00 +draft: false +images: [] +menu: + configuration: + parent: "prologue" +weight: 100100 +toc: true +--- + +## Documentation + +We document the configuration in two ways: + +1. The [YAML] configuration template + [config.template.yml](https://github.com/authelia/authelia/blob/master/config.template.yml) has comments with very + limited documentation on the effective use of a particular option. All documentation lines start with `##`. Lines + starting with a single `#` are [YAML] configuration options which are commented to disable them or as examples. +2. This documentation site. Generally each section of the configuration is in its own section of the documentation + site. Each configuration option is listed in its relevant section as a heading, under that heading generally are two + or three colored labels. + * The `type` label is purple and indicates the [YAML] value type of the variable. It optionally includes some + additional information in parentheses. + * The `default` label is blue and indicates the default value if you don't define the option at all. This is not the + same value as you will see in the examples in all instances, it is the value set when blank or undefined. + * The `required` label changes color. When required it will be red, when not required it will be green, when the + required state depends on another configuration value it is yellow. + +## Validation + +Authelia validates the configuration when it starts. This process checks multiple factors including configuration keys +that don't exist, configuration keys that have changed, the values of the keys are valid, and that a configuration +key isn't supplied at the same time as a secret for the same configuration option. + +You may also optionally validate your configuration against this validation process manually by using the +`authelia validate-config` command. This command is useful prior to upgrading to prevent configuration changes from +impacting downtime in an upgrade. This process does not validate integrations, it only checks that your configuration +syntax is valid. + +```bash +authelia validate-config --config configuration.yml +``` + +[YAML]: https://yaml.org/ diff --git a/docs/content/en/configuration/prologue/migration.md b/docs/content/en/configuration/prologue/migration.md new file mode 100644 index 000000000..242a01f51 --- /dev/null +++ b/docs/content/en/configuration/prologue/migration.md @@ -0,0 +1,97 @@ +--- +title: "Migration" +description: "Information regarding configuration migration." +lead: "An introduction into configuring Authelia." +date: 2022-03-20T12:52:27+11:00 +draft: false +images: [] +menu: + configuration: + parent: "prologue" +weight: 100300 +toc: true +aliases: + - /docs/configuration/migration.html +--- + +This section documents changes in the configuration which may require manual migration by the administrator. Typically +this only occurs when a configuration key is renamed or moved to a more appropriate location. + +## Format + +The migrations are formatted in a table with the old key and the new key. Periods indicate a different section which can +be represented in [YAML] as a dictionary i.e. it's indented. + +In our table `server.host` with a value of `0.0.0.0` is represented in [YAML] like this: + +```yaml +server: + host: 0.0.0.0 +``` + +## Policy + +Our deprecation policy for configuration keys is 3 minor versions. For example if a configuration option is deprecated +in version 4.30.0, it will remain as a warning for 4.30.x, 4.31.x, and 4.32.x; then it will become a fatal error in +4.33.0+. + +## Migrations + +### 4.33.0 + +The options deprecated in version [4.30.0](#4300) have been fully removed as per our deprecation policy and warnings +logged for users. + +### 4.30.0 + +The following changes occurred in 4.30.0: + +| Previous Key | New Key | +|:-------------:|:----------------------:| +| host | server.host | +| port | server.port | +| tls_key | server.tls.key | +| tls_cert | server.tls.certificate | +| log_level | log.level | +| log_file_path | log.file_path | +| log_format | log.format | + +*__Please Note:__ you can no longer define secrets for providers that you are not using. For example if you're using the +[filesystem notifier](../notifications/introduction.md) you must ensure that the `AUTHELIA_NOTIFIER_SMTP_PASSWORD_FILE` +environment variable or other environment variables set. This also applies to other providers like +[storage](../storage/introduction.md) and [authentication backend](../first-factor/introduction.md).* + +#### Kubernetes 4.30.0 + +*__Please Note:__ if you're using Authelia with Kubernetes and are not using the provided +[helm chart](https://charts.authelia.com) you will be required to +[configure the enableServiceLinks](../../integration/kubernetes/introduction/index.md#enable-service-links) option.* + +### 4.25.0 + +The following changes occurred in 4.25.0: + +| Previous Key | New Key | +|:-----------------------------------------------:|:-----------------------------------------------:| +| authentication_backend.ldap.tls.skip_verify | authentication_backend.ldap.tls.skip_verify | +| authentication_backend.ldap.minimum_tls_version | authentication_backend.ldap.tls.minimum_version | +| notifier.smtp.disable_verify_cert | notifier.smtp.tls.skip_verify | +| notifier.smtp.trusted_cert | certificates_directory | + +*__Please Note:__ `certificates_directory` is not a direct replacement for the `notifier.smtp.trusted_cert`, instead +of being the path to a specific file it is a path to a directory containing certificates trusted by Authelia. This +affects other services like LDAP as well.* + +### 4.7.0 + +The following changes occurred in 4.7.0: + +| Previous Key | New Key | +|:------------:|:---------:| +| logs_level | log_level | +| logs_file | log_file | + +*__Please Note:__ The new keys also changed in [4.30.0](#4.30.0) so you will need to update them to the new values if you +are using [4.30.0](#4.30.0) or newer instead of the new keys listed here.* + +[YAML]: https://yaml.org/ diff --git a/docs/content/en/configuration/second-factor/_index.md b/docs/content/en/configuration/second-factor/_index.md new file mode 100644 index 000000000..ddf76c132 --- /dev/null +++ b/docs/content/en/configuration/second-factor/_index.md @@ -0,0 +1,9 @@ +--- +title : "Second Factor" +description: "Second Factor methods configuration" +lead: "" +date: 2022-03-20T12:52:27+11:00 +draft: false +images: [] +weight: 103000 +--- diff --git a/docs/content/en/configuration/second-factor/duo.md b/docs/content/en/configuration/second-factor/duo.md new file mode 100644 index 000000000..f9cc29e8d --- /dev/null +++ b/docs/content/en/configuration/second-factor/duo.md @@ -0,0 +1,71 @@ +--- +title: "Duo / Mobile Push" +description: "Configuring the Duo Mobile Push Notification Second Factor Method." +lead: "" +date: 2022-03-20T12:52:27+11:00 +draft: false +images: [] +menu: + configuration: + parent: "second-factor" +weight: 103200 +toc: true +aliases: + - /docs/configuration/duo-push-notifications.html +--- + +Authelia supports mobile push notifications relying on [Duo]. + +Follow the instructions in the dedicated [documentation](../../overview/authentication/push-notification/index.md) for +instructions on how to set up push notifications in Authelia. + +__Note:__ The configuration options in the following sections are noted as required. They are however only required when +you have this section defined. i.e. if you don't wish to use the [Duo] push notifications you can just not define this +section of the configuration. + +## Configuration + +```yaml +duo_api: + disable: false + hostname: api-123456789.example.com + integration_key: ABCDEF + secret_key: 1234567890abcdefghifjkl + enable_self_enrollment: false +``` + +## Options + +### Disable + +{{< confkey type="boolean" default="false" required="no" >}} + +Disables Duo. If the hostname, integration_key, and secret_key are all empty strings or undefined this is automatically +true. + +### hostname + +{{< confkey type="string" required="yes" >}} + +The [Duo] API hostname supplied by [Duo]. + +### integration_key + +{{< confkey type="string" required="yes" >}} + +The non-secret [Duo] integration key. Similar to a client identifier. + +### secret_key + +{{< confkey type="string" required="yes" >}} + +The secret [Duo] key used to verify your application is valid. It's recommended to set this via a +[secret](../methods/secrets.md). + +### enable_self_enrollment + +{{< confkey type="boolean" default="false" required="no" >}} + +Enables [Duo] device self-enrollment from within the Authelia portal. + +[Duo]: https://duo.com/ diff --git a/docs/content/en/configuration/second-factor/introduction.md b/docs/content/en/configuration/second-factor/introduction.md new file mode 100644 index 000000000..ebf14f803 --- /dev/null +++ b/docs/content/en/configuration/second-factor/introduction.md @@ -0,0 +1,25 @@ +--- +title: "Second Factor" +description: "Configuring Authelia Second Factor Authentication." +lead: "Authelia provides a number of 2FA methods. This section describes these methods." +date: 2022-03-20T12:52:27+11:00 +draft: false +images: [] +menu: + configuration: + parent: "second-factor" +weight: 103100 +toc: true +--- + +## One Time Password + +Authelia supports configuring [Time-based One Time Password](time-based-one-time-password.md)'s. + +## Security Key + +Authelia supports configuring [WebAuthn](webauthn.md) Security Keys. + +## Mobile Push + +Authelia supports configuring [Duo](duo.md) to provide a mobile push service. diff --git a/docs/configuration/one-time-password.md b/docs/content/en/configuration/second-factor/time-based-one-time-password.md similarity index 61% rename from docs/configuration/one-time-password.md rename to docs/content/en/configuration/second-factor/time-based-one-time-password.md index 2b85a3d78..e95507a14 100644 --- a/docs/configuration/one-time-password.md +++ b/docs/content/en/configuration/second-factor/time-based-one-time-password.md @@ -1,17 +1,31 @@ --- -layout: default -title: Time-based One-Time Password -parent: Configuration -nav_order: 16 +title: "Time-based One Time Password" +description: "Configuring the Time-based One Time Password Second Factor Method." +lead: "Authelia supports utilizing time-based one-time passwords as a 2FA method." +date: 2022-03-20T12:52:27+11:00 +draft: false +images: [] +menu: + configuration: + parent: "second-factor" +weight: 103300 +toc: true +aliases: + - /c/totp + - /docs/configuration/one-time-password.html --- -# Time-based One-Time Password +The OTP method *Authelia* uses is the Time-Based One-Time Password Algorithm (TOTP) [RFC6238] which is an extension of +HMAC-Based One-Time Password Algorithm (HOTP) [RFC4226]. -The OTP method _Authelia_ uses is the Time-Based One-Time Password Algorithm (TOTP) [RFC6238] which is an extension of -HMAC-Based One-Time Password Algorithm (HOTP) [RFC4226]. You have the option to tune the settings of theTOTP generation, -and you can see a full example of TOTP configuration below, as well as sections describing them. +You have the option to tune the settings of the TOTP generation, and you can see a full example of TOTP configuration +below, as well as sections describing them. + +Keep in mind the default settings are chosen for compatibility. Many applications do not support digits other than 6, +and many only support SHA1. ## Configuration + ```yaml totp: disable: false @@ -26,26 +40,14 @@ totp: ## Options ### disable -
-type: boolean -{: .label .label-config .label-purple } -default: false -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
+ +{{< confkey type="boolean" default="false" required="no" >}} This disables One-Time Password (TOTP) if set to true. ### issuer -
-type: string -{: .label .label-config .label-purple } -default: Authelia -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
+ +{{< confkey type="string" default="Authelia" required="no" >}} Applications generating one-time passwords usually display an issuer to differentiate applications registered by the user. @@ -54,48 +56,37 @@ Authelia allows customisation of the issuer to differentiate the entry created by Authelia from others. ### algorithm -
-type: string -{: .label .label-config .label-purple } -default: sha1 -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
-_**Important Note:** Many TOTP applications do not support this option. It is strongly advised you find out which +{{< confkey type="string" default="sha1" required="no" >}} + +*__Important Note:__ Many TOTP applications do not support this option. It is strongly advised you find out which applications your users use and test them before changing this option. It is insufficient to test that the application -can add the key, it must also authenticate with Authelia as some applications silently ignore these options. Bitwarden -is the only one that has been tested at this time. If you'd like to contribute to documenting support for this option -please see [Issue 2650](https://github.com/authelia/authelia/issues/2650)._ +can add the key, it must also authenticate with Authelia as some applications silently ignore these options. Bitwarden +is the only one that has been tested at this time. If you'd like to contribute to documenting support for this option +please see [Issue 2650](https://github.com/authelia/authelia/issues/2650).* The algorithm used for the TOTP key. Possible Values (case-insensitive): -- `sha1` -- `sha256` -- `sha512` + +* `sha1` +* `sha256` +* `sha512` Changing this value only affects newly registered TOTP keys. See the [Registration](#registration) section for more information. ### digits -
-type: integer -{: .label .label-config .label-purple } -default: 6 -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
-_**Important Note:** Some TOTP applications do not support this option. It is strongly advised you find out which +{{< confkey type="integer" default="6" required="no" >}} + +*__Important Note:__ Some TOTP applications do not support this option. It is strongly advised you find out which applications your users use and test them before changing this option. It is insufficient to test that the application can add the key, it must also authenticate with Authelia as some applications silently ignore these options. Bitwarden is the only one that has been tested at this time. If you'd like to contribute to documenting support for this option -please see [Issue 2650](https://github.com/authelia/authelia/issues/2650)._ +please see [Issue 2650](https://github.com/authelia/authelia/issues/2650).* -The number of digits a user needs to input to perform authentication. It's generally not recommended for this to be +The number of digits a user needs to input to perform authentication. It's generally not recommended for this to be altered as many TOTP applications do not support anything other than 6. What's worse is some TOTP applications allow you to add the key, but do not use the correct number of digits specified by the key. @@ -105,16 +96,10 @@ Changing this value only affects newly registered TOTP keys. See the [Registrati information. ### period -
-type: integer -{: .label .label-config .label-purple } -default: 30 -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
-The period of time in seconds between key rotations or the time element of TOTP. Please see the +{{< confkey type="integer" default="30" required="no" >}} + +The period of time in seconds between key rotations or the time element of TOTP. Please see the [input validation](#input-validation) section for how this option and the [skew](#skew) option interact with each other. It is recommended to keep this value set to 30, the minimum is 15. @@ -123,50 +108,40 @@ Changing this value only affects newly registered TOTP keys. See the [Registrati information. ### skew -
-type: integer -{: .label .label-config .label-purple } -default: 1 -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
-The number of one time passwords either side of the current valid one time password that should also be considered valid. +{{< confkey type="integer" default="1" required="no" >}} + +The number of one time passwords either side of the current valid one time password that should also be considered valid. The default of 1 results in 3 one time passwords valid. A setting of 2 would result in 5. With the default period of 30 -this would result in 90 and 150 seconds of valid one time passwords respectively. Please see the +this would result in 90 and 150 seconds of valid one time passwords respectively. Please see the [input validation](#input-validation) section for how this option and the [period](#period) option interact with each other. Changing this value affects all TOTP validations, not just newly registered ones. ### secret_size -
-type: integer -{: .label .label-config .label-purple } -default: 32 -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
-The length in bytes of generated shared secrets. The minimum is 20 (or 160 bits), and the default is 32 (or 256 bits). +{{< confkey type="integer" default="32" required="no" >}} + +The length in bytes of generated shared secrets. The minimum is 20 (or 160 bits), and the default is 32 (or 256 bits). In most use cases 32 is sufficient. Though some authenticators may have issues with more than the minimum. Our minimum is the recommended value in [RFC4226], though technically according to the specification 16 bytes (or 128 bits) is the minimum. ## Registration -When users register their TOTP device for the first time, the current [issuer](#issuer), [algorithm](#algorithm), and -[period](#period) are used to generate the TOTP link and QR code. These values are saved to the database for future -validations. -This means if the configuration options are changed, users will not need to regenerate their keys. This functionality +When users register their TOTP device for the first time, the current [issuer](#issuer), [algorithm](#algorithm), and +[period](#period) are used to generate the TOTP link and QR code. These values are saved to the database for future +validations. + +This means if the configuration options are changed, users will not need to regenerate their keys. This functionality takes effect from 4.33.0 onwards, previously the effect was the keys would just fail to validate. If you'd like to force -users to register a new device, you can delete the old device for a particular user by using the +users to register a new device, you can delete the old device for a particular user by using the `authelia storage totp delete ` command regardless of if you change the settings or not. ## Input Validation -The period and skew configuration parameters affect each other. The default values are a period of 30 and a skew of 1. + +The period and skew configuration parameters affect each other. The default values are a period of 30 and a skew of 1. It is highly recommended you do not change these unless you wish to set skew to 0. These options affect security by changing the length of time a one-time password is valid for. The formula to calculate @@ -174,17 +149,19 @@ the effective validity period is `period + (period * skew * 2)`. For example per seconds of validity, and period 30 and skew 2 would result in 150 seconds of validity. ## System time accuracy -It's important to note that if the system time is not accurate enough then clients will seemingly not generate valid -passwords for TOTP. Conversely this is the same when the client time is not accurate enough. This is due to the Time-based -One Time Passwords being time-based. -Authelia by default checks the system time against an [NTP server](./ntp.md#address) on startup. This helps to prevent -a time synchronization issue on the server being an issue. There is however no effective and reliable way to check the -clients. +It's important to note that if the system time is not accurate enough then clients will seemingly not generate valid +passwords for TOTP. Conversely this is the same when the client time is not accurate enough. This is due to the +Time-based One Time Passwords being time-based. + +Authelia by default checks the system time against an [NTP server](../miscellaneous/ntp.md) on startup. This helps to +prevent a time synchronization issue on the server being an issue. There is however no effective and reliable way to +check the clients. ## Encryption -The TOTP secret is [encrypted](storage/index.md#encryption_key) in the database in version 4.33.0 and above. This is so -a user having access to only the database cannot easily compromise your two-factor authentication method. + +The TOTP secret is [encrypted](../storage/introduction.md#encryption_key) in the database in version 4.33.0 and above. +This is so a user having access to only the database cannot easily compromise your two-factor authentication method. This may be inconvenient for some users who wish to export TOTP keys from Authelia to other services. As such there is a command specifically for exporting TOTP configurations from the database. These commands require the configuration or @@ -192,21 +169,21 @@ at least a minimal configuration that has the storage backend connection details Export in [Key URI Format](https://github.com/google/google-authenticator/wiki/Key-Uri-Format): -```shell -$ authelia storage totp export --format uri +```bash +authelia storage totp export --format uri ``` Export as CSV: -```shell -$ authelia storage totp export --format csv +```bash +authelia storage totp export --format csv ``` Help: -```shell -$ authelia storage totp export --help +```bash +authelia storage totp export --help ``` -[RFC4226]: https://datatracker.ietf.org/doc/html/rfc4226 -[RFC6238]: https://datatracker.ietf.org/doc/html/rfc6238 \ No newline at end of file +[RFC4226]: https://www.rfc-editor.org/rfc/rfc4226.html +[RFC6238]: https://www.rfc-editor.org/rfc/rfc6238.html diff --git a/docs/configuration/webauthn.md b/docs/content/en/configuration/second-factor/webauthn.md similarity index 57% rename from docs/configuration/webauthn.md rename to docs/content/en/configuration/second-factor/webauthn.md index d8ac50e19..c194a16b0 100644 --- a/docs/configuration/webauthn.md +++ b/docs/content/en/configuration/second-factor/webauthn.md @@ -1,13 +1,21 @@ --- -layout: default -title: Webauthn -parent: Configuration -nav_order: 17 +title: "WebAuthn" +description: "Configuring the WebAuthn Second Factor Method." +lead: "WebAuthn is the modern browser security key specification that Authelia supports. This section describes configuring it." +date: 2022-03-20T12:52:27+11:00 +draft: false +images: [] +menu: + configuration: + parent: "second-factor" +weight: 103400 +toc: true +aliases: + - /docs/configuration/webauthn.html --- -The Webauthn section has tunable options for the Webauthn implementation. - ## Configuration + ```yaml webauthn: disable: false @@ -20,46 +28,29 @@ webauthn: ## Options ### disable -
-type: boolean -{: .label .label-config .label-purple } -default: false -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
-This disables Webauthn if set to true. +{{< confkey type="boolean" default="false" required="no" >}} + +This disables WebAuthn if set to true. ### display_name -
-type: string -{: .label .label-config .label-purple } -default: Authelia -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
+ +{{< confkey type="string" default="Authelia" required="no" >}} Sets the display name which is sent to the client to be displayed. It's up to individual browsers and potentially individual operating systems if and how they display this information. -See the [W3C Webauthn Documentation](https://www.w3.org/TR/webauthn-2/#dom-publickeycredentialentity-name) for more information. +See the [W3C WebAuthn Documentation](https://www.w3.org/TR/webauthn-2/#dom-publickeycredentialentity-name) for more +information. ### attestation_conveyance_preference -
-type: string -{: .label .label-config .label-purple } -default: indirect -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
+ +{{< confkey type="string" default="indirect" required="no" >}} Sets the conveyance preference. Conveyancing allows collection of attestation statements about the authenticator such as the AAGUID. The AAGUID indicates the model of the device. -See the [W3C Webauthn Documentation](https://www.w3.org/TR/webauthn-2/#enum-attestation-convey) for more information. +See the [W3C WebAuthn Documentation](https://www.w3.org/TR/webauthn-2/#enum-attestation-convey) for more information. Available Options: @@ -70,18 +61,12 @@ Available Options: | direct | The client will be instructed to perform conveyancing with an attestation statement directly signed by the device | ### user_verification -
-type: string -{: .label .label-config .label-purple } -default: preferred -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
-Sets the user verification preference. +{{< confkey type="string" default="preferred" required="no" >}} -See the [W3C Webauthn Documentation](https://www.w3.org/TR/webauthn-2/#enum-userVerificationRequirement) for more information. +Sets the user verification preference. + +See the [W3C WebAuthn Documentation](https://www.w3.org/TR/webauthn-2/#enum-userVerificationRequirement) for more information. Available Options: @@ -92,18 +77,14 @@ Available Options: | required | The client will ask the user for verification or will fail if the device does not support verification | ### timeout -
-type: string (duration) -{: .label .label-config .label-purple } -default: 60s -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
-This adjusts the requested timeout for a Webauthn interaction. The period of time is in -[duration notation format](index.md#duration-notation-format). +{{< confkey type="duration" default="60s" required="no" >}} + +*__Note:__ This setting uses the [duration notation format](../prologue/common.md#duration-notation-format). Please see +the [common options](../prologue/common.md#duration-notation-format) documentation for information on this format.* + +This adjusts the requested timeout for a WebAuthn interaction. ## FAQ -See the [Security Key FAQ](../features/2fa/security-key.md#faq) for the FAQ. +See the [Security Key FAQ](../../overview/authentication/security-key/index.md#faq) for the FAQ. diff --git a/docs/content/en/configuration/security/_index.md b/docs/content/en/configuration/security/_index.md new file mode 100644 index 000000000..077d90171 --- /dev/null +++ b/docs/content/en/configuration/security/_index.md @@ -0,0 +1,9 @@ +--- +title: "Security" +description: "Security Related Configuration" +lead: "" +date: 2022-03-20T12:52:27+11:00 +draft: false +images: [] +weight: 104000 +--- diff --git a/docs/configuration/access-control.md b/docs/content/en/configuration/security/access-control.md similarity index 61% rename from docs/configuration/access-control.md rename to docs/content/en/configuration/security/access-control.md index 7f43ca3b7..32ba44151 100644 --- a/docs/configuration/access-control.md +++ b/docs/content/en/configuration/security/access-control.md @@ -1,14 +1,20 @@ --- -layout: default -title: Access Control -parent: Configuration -nav_order: 1 +title: "Access Control" +description: "Configuring the Access Control or RBAC settings." +lead: "Authelia supports a comprehensive access control system. This section describes configuring this." +date: 2022-03-20T12:52:27+11:00 +draft: false +images: [] +menu: + configuration: + parent: "security" +weight: 104200 +toc: true +aliases: + - /c/acl + - /docs/configuration/access-control.html --- -# Access Control -{: .no_toc } - - ## Configuration ```yaml @@ -17,17 +23,16 @@ access_control: networks: - name: internal networks: - - 10.0.0.0/8 - - 172.16.0.0/12 - - 192.168.0.0/18 - + - '10.0.0.0/8' + - '172.16.0.0/12' + - '192.168.0.0/18' rules: - - domain: 'public.example.com' - domain_regex: '^\d+\.public.example.com$' + - domain: 'private.example.com' + domain_regex: '^(\d+\-)?priv-img.example.com$' policy: one_factor networks: - - internal - - 1.1.1.1 + - 'internal' + - '1.1.1.1' subject: - ['user:adam'] - ['user:fred'] @@ -42,14 +47,8 @@ access_control: ## Options ### default_policy -
-type: string -{: .label .label-config .label-purple } -default: deny -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
+ +{{< confkey type="string" default="deny" required="no" >}} The default [policy](#policies) defines the policy applied if no [rules](#rules) section apply to the information known about the request. It is recommended that this is configured to [deny](#deny) for security reasons. Sites which you do @@ -59,41 +58,32 @@ Authelia at all for performance reasons. See [Policies](#policies) for more information. ### networks (global) -
-type: list -{: .label .label-config .label-purple } -required: no -{: .label .label-config .label-green } -
-The main/global networks section contains a list of networks with a name label that can be reused in the -[rules](#networks) section instead of redefining the same networks over and over again. This additionally makes +{{< confkey type="list" required="no" >}} + +The main/global networks section contains a list of networks with a name label that can be reused in the +[rules](#networks) section instead of redefining the same networks over and over again. This additionally makes complicated network related configuration a lot cleaner and easier to read. This section has two options, `name` and `networks`. Where the `networks` section is a list of IP addresses in CIDR -notation and where `name` is a friendly name to label the collection of networks for reuse in the [networks](#networks) +notation and where `name` is a friendly name to label the collection of networks for reuse in the [networks](#networks) section of the [rules](#rules) section below. This configuration option *does nothing* by itself, it's only useful if you use these aliases in the [rules](#networks) section below. ### rules -
-type: list -{: .label .label-config .label-purple } -required: no -{: .label .label-config .label-green } -
+ +{{< confkey type="list" required="no" >}} The rules have many configuration options. A rule matches when all criteria of the rule match the request excluding the `policy` which is the [policy](#policies) applied to the request. A rule defines two primary things: -* the policy applied when all criteria match. - +* the policy applied when all criteria match * the matching criteria of the request presented to the reverse proxy - + The criteria is broken into several parts: * [domain](#domain): domain or list of domains targeted by the request. @@ -104,51 +94,42 @@ The criteria is broken into several parts: * [methods](#methods): the http methods used in the request. A rule is matched when all criteria of the rule match. Rules are evaluated in sequential order, and the first rule that -is a match for a given request is the rule applied; subsequent rules have *no effect*. This is particularly -**important** for bypass rules. Bypass rules should generally appear near the top of the rules list. However you need to -carefully evaluate your rule list **in order** to see which rule matches a particular scenario. A comprehensive +is a match for a given request is the rule applied; subsequent rules have *no effect*. This is particularly +__important__ for bypass rules. Bypass rules should generally appear near the top of the rules list. However you need to +carefully evaluate your rule list __in order__ to see which rule matches a particular scenario. A comprehensive understanding of how rules apply is also recommended. #### domain -
-type: list(string) -{: .label .label-config .label-purple } -required: yes -{: .label .label-config .label-red } -
-_**Required:** This criteria OR the [domain_regex](#domain_regex) criteria are required._ +{{< confkey type="list(string)" required="yes" >}} -This criteria matches the domain name and has two methods of configuration, either as a single string or as a list of -strings. When it's a list of strings the rule matches when **any** of the domains in the list match the request domain. -When used in conjunction with [domain_regex](#domain_regex) the rule will match when either the [domain](#domain) or the +*__Required:__ This criteria and/or the [domain_regex](#domain_regex) criteria are required.* + +This criteria matches the domain name and has two methods of configuration, either as a single string or as a list of +strings. When it's a list of strings the rule matches when __any__ of the domains in the list match the request domain. +When used in conjunction with [domain_regex](#domain_regex) the rule will match when either the [domain](#domain) or the [domain_regex](#domain_regex) criteria matches. Rules may start with a few different wildcards: -* The standard wildcard is `*.`, which when in front of a domain means that any subdomain is effectively a match. For +* The standard wildcard is `*.`, which when in front of a domain means that any subdomain is effectively a match. For example `*.example.com` would match `abc.example.com` and `secure.example.com`. When using a wildcard like this the - string **must** be quoted like `"*.example.com"`. - + string __must__ be quoted like `"*.example.com"`. * The user wildcard is `{user}.`, which when in front of a domain dynamically matches the username of the user. For - example `{user}.example.com` would match `fred.example.com` if the user logged in was named `fred`. _**Warning:** this is + example `{user}.example.com` would match `fred.example.com` if the user logged in was named `fred`. *__Warning:__ this is officially deprecated as the [domain_regex](#domain_regex) criteria completely replaces the functionality in a much more useful way. It is strongly recommended you do not use this as it will be removed in a future version, most likely - v5.0.0._ - + v5.0.0.* * The group wildcard is `{group}.`, which when in front of a domain dynamically matches if the logged in user has the group in that location. For example `{group}.example.com` would match `admins.example.com` if the user logged in was - in the following groups `admins,users,people` because `admins` is in the list. _**Warning:** this is - officially deprecated as the [domain_regex](#domain_regex) criteria completely replaces the functionality in a much - more useful way. It is strongly recommended you do not use this as it will be removed in a future version, most likely - v5.0.0._ + in the following groups `admins,users,people` because `admins` is in the list. -Domains in this section must be the domain configured in the [session](./session/index.md#domain) configuration or -subdomains of that domain. This is because a website can only write cookies for a domain it is part of. It is +Domains in this section must be the domain configured in the [session](../session/introduction.md#domain) configuration +or subdomains of that domain. This is because a website can only write cookies for a domain it is part of. It is theoretically possible for us to do this with multiple domains however we would have to be security conscious in our implementation, and it is not currently a priority. -Examples: +##### Examples *Single domain of `*.example.com` matched. All rules in this list are effectively the same rule just expressed in different ways.* @@ -163,7 +144,7 @@ access_control: policy: bypass ``` -*Multiple domains matched. These rules would match either `apple.example.com` or `orange.example.com`. All rules in this +*Multiple domains matched. These rules will match either `apple.example.com` or `orange.example.com`. All rules in this list are effectively the same rule just expressed in different ways.* ```yaml @@ -177,27 +158,35 @@ access_control: policy: bypass ``` +*Multiple domains matched either via a static domain or via a [domain_regex](#domain_regex). This rule will match +either `apple.example.com`, `pub-data.example.com`, or `img-data.example.com`.* + +```yaml +access_control: + rules: + - domain: 'apple.example.com' + domain_regex: '^(pub|img)-data\.example\.com$' + policy: bypass +``` + ### domain_regex -
-type: list(string) -{: .label .label-config .label-purple } -required: yes -{: .label .label-config .label-red } -
-_**Required:** This criteria OR the [domain](#domain) criteria are required._ +{{< confkey type="list(string)" required="yes" >}} -_**Important Note:** If you intend to use this criteria with a bypass rule please read -[bypass and subjects](#bypass-and-user-identity) before doing so._ +*__Required:__ This criteria and/or the [domain](#domain) criteria are required.* -_**Important Note:** to utilize regex you must escape it properly. See [regex](./index.md#regex) for more information._ +*__Important Note:__ If you intend to use this criteria with a bypass rule please read +[bypass and subjects](#bypass-and-user-identity) before doing so.* + +*__Important Note:__ to utilize regex you must escape it properly. See +[regular expressions](../prologue/common.md#regular-expressions) for more information.* This criteria matches the domain name and has two methods of configuration, either as a single string or as a list of -strings. When it's a list of strings the rule matches when **any** of the domains in the list match the request domain. +strings. When it's a list of strings the rule matches when __any__ of the domains in the list match the request domain. When used in conjunction with [domain](#domain) the rule will match when either the [domain](#domain) or the [domain_regex](#domain_regex) criteria matches. -This criteria takes any standard go regex pattern to match the requests. We additionally utilize two special named match +This criteria takes any standard go regex pattern to match the requests. We additionally utilize two special named match groups which match attributes of the user: | Group Name | Match Value | @@ -207,61 +196,65 @@ groups which match attributes of the user: For the group match it matches if the user has any group name that matches, and both matches are case-insensitive due to the fact domain names should not be compared in a case-sensitive way as per the -[RFC4343](https://datatracker.ietf.org/doc/html/rfc4343) abstract and -[RFC3986](https://www.rfc-editor.org/rfc/rfc3986#section-3.2.2) section 3.2.2. +[RFC4343](https://www.rfc-editor.org/rfc/rfc4343.html) abstract and +[RFC3986 Section 3.2.2](https://www.rfc-editor.org/rfc/rfc3986#section-3.2.2). -Examples: +#### Examples + +*An advanced multiple domain regex example with user/group matching. This will match the user `john` in the groups +`example` and `example1`, when the request is made to `user-john.example.com`, `group-example.example.com`, or +`group-example1.example.com`, it would not match when the request is made to `user-fred.example.com` or +`group-admin.example.com`.* ```yaml access_control: rules: - - domain: - - apple.example.com - - banana.example.com - policy: bypass - domain_regex: - '^user-(?P\w+)\.example\.com$' - '^group-(?P\w+)\.example\.com$' policy: one_factor ``` +*Multiple domains example, one with a static domain and one with a regex domain. This will match requests to +`protected.example.com`, `img-private.example.com`, or `data-private.example.com`.* + +```yaml +access_control: + rules: + - domain: 'protected.example.com' + - domain_regex: '^(img|data)-private\.example\.com' + policy: one_factor +``` + #### policy -
-type: string -{: .label .label-config .label-purple } -required: yes -{: .label .label-config .label-red } -
+ +{{< confkey type="string" required="yes" >}} The specific [policy](#policies) to apply to the selected rule. This is not criteria for a match, this is the action to take when a match is made. -### subject -
-type: list(list(string)) -{: .label .label-config .label-purple } -required: no -{: .label .label-config .label-green } -
+#### subject -***Note:** this rule criteria **may not** be used for the `bypass` policy the minimum required authentication level to -identify the subject is `one_factor`. We have taken an opinionated stance on preventing this configuration as it could -result in problematic security scenarios with badly thought out configurations and cannot see a likely configuration -scenario that would require users to do this. If you have a scenario in mind please open an +{{< confkey type="list(list(string))" required="no" >}} + +*__Note:__ this rule criteria __may not__ be used for the `bypass` policy the minimum required authentication level to +identify the subject is `one_factor`. We have taken an opinionated stance on preventing this configuration as it could +result in problematic security scenarios with badly thought out configurations and cannot see a likely configuration +scenario that would require users to do this. If you have a scenario in mind please open an [issue](https://github.com/authelia/authelia/issues/new) on GitHub.* -This criteria matches identifying characteristics about the subject. This is either user's name or the name of the -group a user belongs to. This allows you to effectively control exactly what each user is authorized to access or to -specifically require two-factor authentication to specific users. Subjects are prefixed with either `user:` or `group:` -to identify which part of the identity to check. +This criteria matches identifying characteristics about the subject. Currently this is either user or groups the user +belongs to. This allows you to effectively control exactly what each user is authorized to access or to specifically +require two-factor authentication to specific users. Subjects are prefixed with either `user:` or `group:` to identify +which part of the identity to check. The format of this rule is unique in as much as it is a list of lists. The logic behind this format is to allow for both `OR` and `AND` logic. The first level of the list defines the `OR` logic, and the second level defines the `AND` logic. Additionally each level of these lists does not have to be explicitly defined. -Example: +##### Examples -*Matches when the user has the username `john`, **or** the user is in the groups `admin` **and** `app-name`, **or** the +*Matches when the user has the username `john`, __or__ the user is in the groups `admin` __and__ `app-name`, __or__ the user is in the group `super-admin`. All rules in this list are effectively the same rule just expressed in different ways.* @@ -271,15 +264,15 @@ access_control: - domain: example.com policy: two_factor subject: - - "user:john" - - ["group:admin", "group:app-name"] - - "group:super-admin" + - 'user:john' + - ['group:admin', 'group:app-name'] + - 'group:super-admin' - domain: example.com policy: two_factor subject: - - ["user:john"] - - ["group:admin", "group:app-name"] - - ["group:super-admin"] + - ['user:john'] + - ['group:admin', 'group:app-name'] + - ['group:super-admin'] ``` *Matches when the user is in the `super-admin` group. All rules in this list are effectively the same rule just @@ -290,24 +283,20 @@ access_control: rules: - domain: example.com policy: one_factor - subject: "group:super-admin" - - domain: example.com - policy: one_factor - subject: - - "group:super-admin" + subject: 'group:super-admin' - domain: example.com policy: one_factor subject: - - ["group:super-admin"] + - 'group:super-admin' + - domain: example.com + policy: one_factor + subject: + - ['group:super-admin'] ``` -### methods -
-type: list(string) -{: .label .label-config .label-purple } -required: no -{: .label .label-config .label-green } -
+#### methods + +{{< confkey type="list(string)" required="no" >}} This criteria matches the HTTP request method. This is primarily useful when trying to bypass authentication for specific request types when those requests would prevent essential or public operation of the website. An example is when you @@ -319,7 +308,18 @@ permission to do GET requests, their authentication level was `one_factor`, and who have done requests other than HEAD or GET which means the user experience may suffer. These are the reasons it's only recommended to use this to increase security where essential and for CORS preflight. -Example: +The accepted and valid methods for this configuration option are those specified in well known RFC's. The RFC's and the +relevant methods are listed in this table: + +| RFC | Methods | Additional Documentation | +|:---------:|:-----------------------------------------------------:|:----------------------------------------------------------------:| +| [RFC7231] | GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE | [MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods) | +| [RFC5789] | PATCH | [MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods) | +| [RFC4918] | PROPFIND, PROPPATCH, MKCOL, COPY, MOVE, LOCK, UNLOCK | | + +##### Examples + +*Bypass `OPTIONS` requests to the `example.com` domain.* ```yaml access_control: @@ -330,29 +330,14 @@ access_control: - OPTIONS ``` -The accepted and valid methods for this configuration option are those specified in well known RFC's. The RFC's and the -relevant methods are listed in this table: +#### networks -| RFC | Methods | Additional Documentation | -|:--------------------------------------------------------:|:-----------------------------------------------------:|:----------------------------------------------------------------:| -| [RFC7231](https://datatracker.ietf.org/doc/html/rfc7231) | GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE | [MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods) | -| [RFC5789](https://datatracker.ietf.org/doc/html/rfc5789) | PATCH | [MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods) | -| [RFC4918](https://datatracker.ietf.org/doc/html/rfc4918) | PROPFIND, PROPPATCH, MKCOL, COPY, MOVE, LOCK, UNLOCK | | +{{< confkey type="list(string)" required="no" >}} - - -### networks -
-type: list(string) -{: .label .label-config .label-purple } -required: no -{: .label .label-config .label-green } -
- -This criteria is a list of values which can be an IP Address, network address range in CIDR notation, or an alias from -the [global](#networks-global) section. It matches against the first address in the `X-Forwarded-For` header, or if there +This criteria is a list of values which can be an IP Address, network address range in CIDR notation, or an alias from +the [global](#networks-global) section. It matches against the first address in the `X-Forwarded-For` header, or if there are none it will fall back to the IP address of the packet TCP source IP address. For this reason it's important for you -to configure the proxy server correctly in order to accurately match requests with this criteria. ***Note:** you may +to configure the proxy server correctly in order to accurately match requests with this criteria. *__Note:__ you may combine CIDR networks with the alias rules as you please.* The main use case for this criteria is adjust the security requirements of a resource based on the location of a user. @@ -367,9 +352,9 @@ privileges when a user is on the local networks. There are a large number of scenarios regarding networks and the order of the rules. This provides a lot of flexibility for administrators to tune the security to their specific needs if desired. -Examples: +##### Examples -*Require [two_factor](#two_factor) for all clients other than internal clients and `112.134.145.167`. The first two +*Require [two_factor](#two_factor) for all clients other than internal clients and `112.134.145.167`. The first two rules in this list are effectively the same rule just expressed in different ways.* ```yaml @@ -378,45 +363,47 @@ access_control: networks: - name: internal networks: - - 10.0.0.0/8 - - 172.16.0.0/12 - - 192.168.0.0/18 + - '10.0.0.0/8' + - '172.16.0.0/12' + - '192.168.0.0/18' rules: - domain: secure.example.com policy: one_factor networks: - - 10.0.0.0/8 - - 172.16.0.0/12 - - 192.168.0.0/18 - - 112.134.145.167/32 + - '10.0.0.0/8' + - '172.16.0.0/12' + - '192.168.0.0/18' + - '112.134.145.167/32' - domain: secure.example.com policy: one_factor networks: - - internal - - 112.134.145.167/32 + - 'internal' + - '112.134.145.167/32' - domain: secure.example.com policy: two_factor ``` -### resources -
-type: list(string) -{: .label .label-config .label-purple } -required: no -{: .label .label-config .label-green } -
+#### resources -_**Important Note:** to utilize regex you must escape it properly. See [regex](./index.md#regex) for more information._ +{{< confkey type="list(string)" required="no" >}} + +*__Important Note:__ to utilize regex you must escape it properly. See +[regular expressions](../prologue/common.md#regular-expressions) for more information.* This criteria matches the path and query of the request using regular expressions. The rule is expressed as a list of strings. If any one of the regular expressions in the list matches the request it's considered a match. A useful tool -for debugging these regular expressions is called [Rego](https://regoio.herokuapp.com/). +for debugging these regular expressions is called [Regex 101](https://regex101.com/) (ensure you pick the `Golang` +option). -_**Note:** Prior to 4.27.0 the regular expressions only matched the path excluding the query parameters. After 4.27.0 -they match the entire path including the query parameters. When upgrading you may be required to alter some of your -resource rules to get them to operate as they previously did._ +*__Note:__ Prior to 4.27.0 the regular expressions only matched the path excluding the query parameters. After 4.27.0 +they match the entire path including the query parameters. When upgrading you may be required to alter some of your +resource rules to get them to operate as they previously did.* -Examples: +It's important when configuring resource rules that you enclose them in quotes otherwise you may run into some issues +with escaping the expressions. Failure to do so may prevent Authelia from starting. It's technically optional but will +likely save you a lot of time if you do it for all resource rules. + +##### Examples *Applies the [bypass](#bypass) policy when the domain is `app.example.com` and the url is `/api`, or starts with either `/api/` or `/api?`.* @@ -432,36 +419,36 @@ access_control: ## Policies -The policy of the first matching rule in the configured list decides the policy applied to the request, if no rule +The policy of the first matching rule in the configured list decides the policy applied to the request, if no rule matches the request the [default_policy](#default_policy) is applied. ### deny This is the policy applied by default, and is what we recommend as the default policy for all installs. Its effect -is literally to deny the user access to the resource. Additionally you can use this policy to conditionally deny +is literally to deny the user access to the resource. Additionally you can use this policy to conditionally deny access in desired situations. Examples include denying access to an API that has no authentication mechanism built in. ### bypass This policy skips all authentication and allows anyone to use the resource. This policy is not available with a rule -that includes a [subject](#subject) restriction because the minimum authentication level required to obtain information +that includes a [subject](#subject) restriction because the minimum authentication level required to obtain information about the subject is [one_factor](#one_factor). #### bypass and user identity The [bypass](#bypass) policy cannot be used when the rule uses a criteria that requires we know the users identity. This -means: +means: -- If the rule defines [subjects](#subject) criteria -- If the rule defines [domain regex](#domain_regex) criteria which contains either the user or group named match groups +* If the rule defines [subjects](#subject) criteria +* If the rule defines [domain regex](#domain_regex) criteria which contains either the user or group named match groups -This is because these criteria types require knowing who the user is in order to determine if their identity matches the -request. This information can only be known after 1FA, which means the minimum policy that can be used logically is -[one_factor](#one_factor). +This is because these criteria types require knowing who the user is in order to determine if their identity matches the +request. This information can only be known after 1FA, which means the minimum policy that can be used logically is +[one_factor](#one_factor). ### one_factor -This policy requires the user at minimum complete 1FA successfully (username and password). This means if they have +This policy requires the user at minimum complete 1FA successfully (username and password). This means if they have performed 2FA then they will be allowed to access the resource. ### two_factor @@ -479,8 +466,8 @@ access_control: networks: - name: internal networks: - - 10.10.0.0/16 - - 192.168.2.0/24 + - '10.10.0.0/16' + - '192.168.2.0/24' - name: VPN networks: 10.9.0.0/16 rules: @@ -495,10 +482,10 @@ access_control: - domain: 'secure.example.com' policy: one_factor networks: - - internal - - VPN - - 192.168.1.0/24 - - 10.0.0.1 + - 'internal' + - 'VPN' + - '192.168.1.0/24' + - '10.0.0.1' - domain: - 'secure.example.com' @@ -509,7 +496,7 @@ access_control: policy: one_factor - domain: 'mx2.mail.example.com' - subject: "group:admins" + subject: 'group:admins' policy: deny - domain: '*.example.com' @@ -527,7 +514,7 @@ access_control: - domain: dev.example.com resources: - '^/users/john/.*$' - subject: + subject: - ['group:dev', 'user:john'] - 'group:admins' policy: two_factor @@ -535,3 +522,7 @@ access_control: - domain: '{user}.example.com' policy: bypass ``` + +[RFC7231]: https://www.rfc-editor.org/rfc/rfc7231.html +[RFC5789]: https://www.rfc-editor.org/rfc/rfc5789.html +[RFC4918]: https://www.rfc-editor.org/rfc/rfc4918.html diff --git a/docs/content/en/configuration/security/introduction.md b/docs/content/en/configuration/security/introduction.md new file mode 100644 index 000000000..569f02ea2 --- /dev/null +++ b/docs/content/en/configuration/security/introduction.md @@ -0,0 +1,13 @@ +--- +title: "Security" +description: "Security Related Configuration" +lead: "An introduction into configuring the security settings." +date: 2022-03-20T12:52:27+11:00 +draft: false +images: [] +menu: + configuration: + parent: "security" +weight: 104100 +toc: true +--- diff --git a/docs/content/en/configuration/security/password-policy.md b/docs/content/en/configuration/security/password-policy.md new file mode 100644 index 000000000..6722adce8 --- /dev/null +++ b/docs/content/en/configuration/security/password-policy.md @@ -0,0 +1,112 @@ +--- +title: "Password Policy" +description: "Password Policy Configuration" +lead: "Configuring the Password Policy." +date: 2022-04-12T14:40:22+10:00 +draft: false +images: [] +menu: + configuration: + parent: "security" +weight: 104400 +toc: true +aliases: + - /docs/configuration/password_policy.html +--- + +*Authelia* allows administrators to configure an enforced password policy. + +## Configuration + +```yaml +password_policy: + standard: + enabled: false + min_length: 8 + max_length: 0 + require_uppercase: false + require_lowercase: false + require_number: false + require_special: false + zxcvbn: + enabled: false + min_score: 3 +``` + +## Options + +### standard + +This section allows you to enable standard security policies. + +#### enabled + +{{< confkey type="boolean" default="false" required="no" >}} + +Enables standard password policy. + +#### min_length + +{{< confkey type="integer" default="8" required="no" >}} + +Determines the minimum allowed password length. + +#### max_length + +{{< confkey type="integer" default="0" required="no" >}} + +Determines the maximum allowed password length. + +#### require_uppercase + +{{< confkey type="boolean" default="false" required="no" >}} + +Indicates that at least one UPPERCASE letter must be provided as part of the password. + +#### require_lowercase + +{{< confkey type="boolean" default="false" required="no" >}} + +Indicates that at least one lowercase letter must be provided as part of the password. + +#### require_number + +{{< confkey type="boolean" default="false" required="no" >}} + +Indicates that at least one number must be provided as part of the password. + +#### require_special + +{{< confkey type="boolean" default="false" required="no" >}} + +Indicates that at least one special character must be provided as part of the password. + +### zxcvbn + +This password policy enables advanced password strength metering, using [zxcvbn](https://github.com/dropbox/zxcvbn). + +Note that this password policy do not restrict the user's entry it just gives the user feedback as to how strong their +password is. + +#### enabled + +{{< confkey type="boolean" default="false" required="no" >}} + +*__Important Note:__ only one password policy can be applied at a time.* + +Enables zxcvbn password policy. + +#### min_score + +{{< confkey type="integer" default="3" required="no" >}} + +Configures the minimum zxcvbn score allowed for new passwords. There are 5 levels in the zxcvbn score system (taken from +[github.com/dropbox/zxcvbn](https://github.com/dropbox/zxcvbn#usage)): + +* score 0: too guessable: risky password (guesses < 10^3) +* score 1: very guessable: protection from throttled online attacks (guesses < 10^6) +* score 2: somewhat guessable: protection from unthrottled online attacks. (guesses < 10^8) +* score 3: safely unguessable: moderate protection from offline slow-hash scenario. (guesses < 10^10) +* score 4: very unguessable: strong protection from offline slow-hash scenario. (guesses >= 10^10) + +We do not allow score 0, if you set the `min_score` value to 0 instead the default will be used instead. diff --git a/docs/content/en/configuration/security/regulation.md b/docs/content/en/configuration/security/regulation.md new file mode 100644 index 000000000..b425c480f --- /dev/null +++ b/docs/content/en/configuration/security/regulation.md @@ -0,0 +1,57 @@ +--- +title: "Regulation" +description: "Regulation Configuration" +lead: "Configuring the Regulation system." +date: 2022-03-20T12:52:27+11:00 +draft: false +images: [] +menu: + configuration: + parent: "security" +weight: 104300 +toc: true +aliases: + - /docs/configuration/regulation.html +--- + + +__Authelia__ can temporarily ban accounts when there are too many +authentication attempts. This helps prevent brute-force attacks. + +## Configuration + +```yaml +regulation: + max_retries: 3 + find_time: 2m + ban_time: 5m +``` + +## Options + +### max_retries + +{{< confkey type="integer " default="3" required="no" >}} + +The number of failed login attempts before a user may be banned. Setting this option to 0 disables regulation entirely. + +### find_time + +{{< confkey type="duration " default="2m" required="no" >}} + +*__Note:__ This setting uses the [duration notation format](../prologue/common.md#duration-notation-format). Please see +the [common options](../prologue/common.md#duration-notation-format) documentation for information on this format.* + +The period of time analyzed for failed attempts. For +example if you set `max_retries` to 3 and `find_time` to `2m` this means the user must have 3 failed logins in +2 minutes. + +### ban_time + +{{< confkey type="duration" default="5m" required="no" >}} + +*__Note:__ This setting uses the [duration notation format](../prologue/common.md#duration-notation-format). Please see +the [common options](../prologue/common.md#duration-notation-format) documentation for information on this format.* + +The period of time the user is banned for after meeting the `max_retries` and `find_time` configuration. After this +duration the account will be able to login again. diff --git a/docs/content/en/configuration/session/_index.md b/docs/content/en/configuration/session/_index.md new file mode 100644 index 000000000..01866387d --- /dev/null +++ b/docs/content/en/configuration/session/_index.md @@ -0,0 +1,9 @@ +--- +title: "Session" +description: "Session Configuration" +lead: "" +date: 2022-03-20T12:52:27+11:00 +draft: false +images: [] +weight: 105000 +--- diff --git a/docs/content/en/configuration/session/introduction.md b/docs/content/en/configuration/session/introduction.md new file mode 100644 index 000000000..f96918bd1 --- /dev/null +++ b/docs/content/en/configuration/session/introduction.md @@ -0,0 +1,129 @@ +--- +title: "Session" +description: "Session Configuration" +lead: "Configuring the Session / Cookie settings." +date: 2022-03-20T12:52:27+11:00 +draft: false +images: [] +menu: + configuration: + parent: "session" +weight: 105100 +toc: true +aliases: + - /c/session + - /docs/configuration/session/ +--- + +__Authelia__ relies on session cookies to authenticate users. When the user visits a website of the protected domain +`example.com` for the first time, Authelia detects that there is no cookie for that user. Consequently, Authelia +redirects the user to the login portal through which the user should authenticate to get a cookie which is valid for +`*.example.com`, meaning all websites of the domain. At the next request, Authelia receives the cookie associated to the +authenticated user and can then order the reverse proxy to let the request pass through to the application. + +## Configuration + +```yaml +session: + name: authelia_session + domain: example.com + same_site: lax + secret: unsecure_session_secret + expiration: 1h + inactivity: 5m + remember_me_duration: 1M +``` + +## Providers + +There are currently two providers for session storage (three if you count Redis Sentinel as a separate provider): + +* Memory (default, stateful, no additional configuration) +* [Redis](redis.md) (stateless). +* [Redis Sentinel](redis.md#high_availability) (stateless, highly available). + +### Kubernetes or High Availability + +It's important to note when picking a provider, the stateful providers are not recommended in High Availability +scenarios like Kubernetes. Each provider has a note beside it indicating it is *stateful* or *stateless* the stateless +providers are recommended. + +## Options + +### name + +{{< confkey type="string" default="authelia_session" required="no" >}} + +The name of the session cookie. By default this is set to authelia_session. It's mostly useful to change this if you are +doing development or running multiple instances of Authelia. + +### domain + +{{< confkey type="string" required="yes" >}} + +The domain the cookie is assigned to protect. This must be the same as the domain Authelia is served on or the root +of the domain. For example if listening on auth.example.com the cookie should be auth.example.com or example.com. + +### same_site + +{{< confkey type="string" default="lax" required="no" >}} + +Sets the cookies SameSite value. Prior to offering the configuration choice this defaulted to None. The new default is +Lax. This option is defined in lower-case. So for example if you want to set it to `Strict`, the value in configuration +needs to be `strict`. + +You can read about the SameSite cookie in detail on the +[MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite). In short setting SameSite to Lax +is generally the most desirable option for Authelia. None is not recommended unless you absolutely know what you're +doing and trust all the protected apps. Strict is not going to work in many use cases and we have not tested it in this +state but it's available as an option anyway. + +### secret + +{{< confkey type="string" required="yes" >}} + +The secret key used to encrypt session data in Redis. It's recommended this is set using a +[secret](../methods/secrets.md). + +We recommend generating a random string with 64 characters or more for this purposes which can be done by following the +[Generating a Random Alphanumeric String](../miscellaneous/guides.md#generating-a-random-alphanumeric-string) +guide. + +### expiration + +{{< confkey type="duration" default="1h" required="no" >}} + +*__Note:__ This setting uses the [duration notation format](../prologue/common.md#duration-notation-format). Please see +the [common options](../prologue/common.md#duration-notation-format) documentation for information on this format.* + +The period of time before the cookie expires and the session is destroyed. This is overriden by +[remember_me_duration](#remember_me_duration) when the remember me box is checked. + +### inactivity + +{{< confkey type="duration" default="5m" required="no" >}} + +*__Note:__ This setting uses the [duration notation format](../prologue/common.md#duration-notation-format). Please see +the [common options](../prologue/common.md#duration-notation-format) documentation for information on this format.* + +The period of time the user can be inactive for until the session is destroyed. Useful if you want long session timers +but don't want unused devices to be vulnerable. + +### remember_me_duration + +{{< confkey type="duration" default="1M" required="no" >}} + +*__Note:__ This setting uses the [duration notation format](../prologue/common.md#duration-notation-format). Please see +the [common options](../prologue/common.md#duration-notation-format) documentation for information on this format.* + +The period of time before the cookie expires and the session is destroyed when the remember me box is checked. Setting +this to `-1` disables this feature entirely. + +## Security + +Configuration of this section has an impact on security. You should read notes in +[security measures](../../overview/security/measures.md#session-security) for more information. + +## Loading a password from a secret instead of inside the configuration + +Password can also be defined using a [secret](../methods/secrets.md). diff --git a/docs/configuration/session/redis.md b/docs/content/en/configuration/session/redis.md similarity index 58% rename from docs/configuration/session/redis.md rename to docs/content/en/configuration/session/redis.md index a8b438b47..d06276490 100644 --- a/docs/configuration/session/redis.md +++ b/docs/content/en/configuration/session/redis.md @@ -1,16 +1,22 @@ --- -layout: default -title: Redis -parent: Session -grand_parent: Configuration -nav_order: 1 +title: "Redis" +description: "Redis Session Configuration" +lead: "Configuring the Redis Session Storage." +date: 2022-03-20T12:52:27+11:00 +draft: false +images: [] +menu: + configuration: + parent: "session" +weight: 105200 +toc: true +aliases: + - /docs/configuration/session/redis.html --- -# Redis - This is a session provider. By default Authelia uses an in-memory provider. Not configuring redis leaves Authelia -[stateful](../../features/statelessness.md). It's important in highly available scenarios to configure this option and -we highly recommend it in production environments. It requires you setup [redis] as well. +[stateful](../../overview/authorization/statelessness.md). It's important in highly available scenarios to configure +this option and we highly recommend it in production environments. It requires you setup [redis] as well. ## Configuration @@ -46,86 +52,55 @@ session: ## Options ### host -
-type: string -{: .label .label-config .label-purple } -required: yes -{: .label .label-config .label-red } -
+ +{{< confkey type="string" required="yes" >}} The [redis] host or unix socket path. If utilising an IPv6 literal address it must be enclosed by square brackets and quoted: + ```yaml host: "[fd00:1111:2222:3333::1]" ``` ### port -
-type: integer -{: .label .label-config .label-purple } -default: 6379 -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
+ +{{< confkey type="integer" default="6379" required="no" >}} The port [redis] is listening on. ### username -
-type: string -{: .label .label-config .label-purple } -required: no -{: .label .label-config .label-green } -
+ +{{< confkey type="string" required="no" >}} The username for [redis authentication](https://redis.io/commands/auth). Only supported in [redis] 6.0+, and [redis] currently offers backwards compatibility with password-only auth. You probably do not need to set this unless you went through the process of setting up [redis ACLs](https://redis.io/topics/acl). ### password -
-type: string -{: .label .label-config .label-purple } -required: no -{: .label .label-config .label-green } -
+ +{{< confkey type="string" required="no" >}} The password for [redis authentication](https://redis.io/commands/auth). +We recommend generating a random string with 64 characters or more for this purposes which can be done by following the +[Generating a Random Alphanumeric String](../miscellaneous/guides.md#generating-a-random-alphanumeric-string) +guide. + ### database_index -
-type: integer -{: .label .label-config .label-purple } -default: 0 -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
+ +{{< confkey type="integer" default="0" required="no" >}} The index number of the [redis] database, the same value as specified with the redis SELECT command. ### maximum_active_connections -
-type: integer -{: .label .label-config .label-purple } -default: 8 -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
+ +{{< confkey type="integer" default="8" required="no" >}} The maximum connections open to [redis] at the same time. ### minimum_idle_connections -
-type: integer -{: .label .label-config .label-purple } -default: 0 -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
+ +{{< confkey type="integer" default="0" required="no" >}} The minimum number of [redis] connections to keep open as long as they don't exceed the maximum active connections. This is useful if there are long delays in establishing connections. @@ -133,7 +108,7 @@ is useful if there are long delays in establishing connections. ### tls If defined enables [redis] over TLS, and additionally controls the TLS connection validation process. You can see how to -configure the tls section [here](../index.md#tls-configuration). +configure the tls section [here](../prologue/common.md#tls-configuration). ### high_availability @@ -141,38 +116,26 @@ When defining this session it enables [redis sentinel] connections. It's possibl the future we may add [redis cluster](https://redis.io/topics/cluster-tutorial). #### sentinel_name -
-type: string -{: .label .label-config .label-purple } -required: yes -{: .label .label-config .label-red } -
+ +{{< confkey type="string" required="yes" >}} The [redis sentinel] master name. This is defined in your [redis sentinel] configuration, it is not a hostname. This must be defined currently for a high availability configuration. #### sentinel_username -
-type: string -{: .label .label-config .label-purple } -required: no -{: .label .label-config .label-green } -
+ +{{< confkey type="string" required="no" >}} The username for the [redis sentinel] connection. If this is provided, it will be used along with the sentinel_password for ACL-based authentication to the Redis Sentinel. If only a password is provided, the [redis sentinel] connection will -be authenticated with traditional requirepass authentication. +be authenticated with traditional [requirepass] authentication. #### sentinel_password -
-type: string -{: .label .label-config .label-purple } -required: no (yes if sentinel_username is supplied) -{: .label .label-config .label-green } -
+ +{{< confkey type="string" required="no (yes if sentinel_username is supplied)" >}} The password for the [redis sentinel] connection. If specified with sentinel_username, configures Authelia to -authenticate to the Redis Sentinel with ACL-based authentication. Otherwise, this is used for requirepass +authenticate to the Redis Sentinel with ACL-based authentication. Otherwise, this is used for [requirepass] authentication. #### nodes @@ -189,52 +152,29 @@ Each node has a host and port configuration. Example: ``` ##### host -
-type: boolean -{: .label .label-config .label-purple } -default: false -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
+ +{{< confkey type="boolean" default="false" required="no" >}} The host of this [redis sentinel] node. ##### port -
-type: integer -{: .label .label-config .label-purple } -default: 26379 -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
+ +{{< confkey type="integer" default="26379" required="no" >}} The port of this [redis sentinel] node. #### route_by_latency -
-type: boolean -{: .label .label-config .label-purple } -default: false -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
+ +{{< confkey type="boolean" default="false" required="no" >}} Prioritizes low latency [redis sentinel] nodes when set to true. #### route_randomly -
-type: boolean -{: .label .label-config .label-purple } -default: false -{: .label .label-config .label-blue } -required: no -{: .label .label-config .label-green } -
+ +{{< confkey type="boolean" default="false" required="no" >}} Randomly chooses [redis sentinel] nodes when set to true. [redis]: https://redis.io [redis sentinel]: https://redis.io/topics/sentinel +[requirepass]: https://redis.io/topics/config diff --git a/docs/content/en/configuration/storage/_index.md b/docs/content/en/configuration/storage/_index.md new file mode 100644 index 000000000..60f7cca21 --- /dev/null +++ b/docs/content/en/configuration/storage/_index.md @@ -0,0 +1,9 @@ +--- +title: "Storage" +description: "Storage Configuration" +lead: "" +date: 2022-03-20T12:52:27+11:00 +draft: false +images: [] +weight: 106000 +--- diff --git a/docs/content/en/configuration/storage/introduction.md b/docs/content/en/configuration/storage/introduction.md new file mode 100644 index 000000000..0d565c539 --- /dev/null +++ b/docs/content/en/configuration/storage/introduction.md @@ -0,0 +1,60 @@ +--- +title: "Storage" +description: "Storage Configuration" +lead: "Configuring the SQL Storage." +date: 2022-03-20T12:52:27+11:00 +draft: false +images: [] +menu: + configuration: + parent: "storage" +weight: 106100 +toc: true +aliases: + - /docs/configuration/storage/ +--- + +__Authelia__ supports multiple storage backends. The backend is used to store user preferences, 2FA device handles and +secrets, authentication logs, etc... + +The available storage backends are listed in the table of contents below. + +## Configuration + +```yaml +storage: + encryption_key: a_very_important_secret + local: {} + mysql: {} + postgres: {} +``` + +## Options + +### encryption_key + +{{< confkey type="string" required="yes" >}} + +The encryption key used to encrypt data in the database. We encrypt data by creating a sha256 checksum of the provided +value, and use that to encrypt the data with the AES-GCM 256bit algorithm. + +The minimum length of this key is 20 characters, however we generally recommend above 64 characters. + +This secret must be generated by the administrator and can +be done by following the +[Generating a Random Alphanumeric String](../miscellaneous/guides.md#generating-a-random-alphanumeric-string) +guide. + +See [securty measures](../../overview/security/measures.md#storage-security-measures) for more information. + +### postgres + +See [PostgreSQL](postgres.md). + +### local + +See [SQLite](sqlite.md). + +### mysql + +See [MySQL](mysql.md). diff --git a/docs/configuration/storage/migrations.md b/docs/content/en/configuration/storage/migrations.md similarity index 78% rename from docs/configuration/storage/migrations.md rename to docs/content/en/configuration/storage/migrations.md index 6666fedb2..b2a77512f 100644 --- a/docs/configuration/storage/migrations.md +++ b/docs/content/en/configuration/storage/migrations.md @@ -1,9 +1,17 @@ --- -layout: default -title: Migrations -parent: Storage Backends -grand_parent: Configuration -nav_order: 5 +title: "Migrations" +description: "Storage Migrations" +lead: "A migration ." +date: 2022-03-20T12:52:27+11:00 +draft: false +images: [] +menu: + configuration: + parent: "storage" +weight: 106200 +toc: true +aliases: + - /docs/configuration/storage/migrations.html --- Storage migrations are important for keeping your database compatible with Authelia. Authelia will automatically upgrade @@ -13,16 +21,16 @@ downgrade your schema with a version of Authelia that supports your current sche ## Schema Version to Authelia Version map This table contains a list of schema versions and the corresponding release of Authelia that shipped with that version. -This means all Authelia versions between two schema versions use the first schema version. +This means all Authelia versions between two schema versions use the first schema version. -For example for version pre1, it is used for all versions between it and the version 1 schema, so 4.0.0 to 4.32.2. In +For example for version pre1, it is used for all versions between it and the version 1 schema, so 4.0.0 to 4.32.2. In this instance if you wanted to downgrade to pre1 you would need to use an Authelia binary with version 4.33.0 or higher. | Schema Version | Authelia Version | Notes | |:--------------:|:----------------:|:--------------------------------------------------------------------------------------------------:| | pre1 | 4.0.0 | Downgrading to this version requires you use the --pre1 flag | | 1 | 4.33.0 | Initial migration managed version | -| 2 | 4.34.0 | Webauthn - added webauthn_devices table, altered totp_config to include device created/used dates | -| 3 | 4.34.2 | Webauthn - fix V2 migration kid column length and provide migration path for anyone on V2 | +| 2 | 4.34.0 | WebAuthn - added webauthn_devices table, altered totp_config to include device created/used dates | +| 3 | 4.34.2 | WebAuthn - fix V2 migration kid column length and provide migration path for anyone on V2 | | 4 | 4.35.0 | Added OpenID Connect storage tables and opaque user identifier tables | | 5 | 4.35.1 | Fixed the oauth2_consent_session table to accept NULL subjects for users who are not yet signed in | diff --git a/docs/content/en/configuration/storage/mysql.md b/docs/content/en/configuration/storage/mysql.md new file mode 100644 index 000000000..6b0ffb827 --- /dev/null +++ b/docs/content/en/configuration/storage/mysql.md @@ -0,0 +1,100 @@ +--- +title: "MySQL" +description: "MySQL Configuration" +lead: "The MySQL storage provider which supports both MySQL and MariaDB." +date: 2022-03-20T12:52:27+11:00 +draft: false +images: [] +menu: + configuration: + parent: "storage" +weight: 106600 +toc: true +aliases: + - /docs/configuration/storage/mariadb.html + - /docs/configuration/storage/mysql.html +--- + +## Version support + +When using MySQL or MariaDB we recommend using the latest version that is officially supported by the MySQL or MariaDB +developers. We also suggest checking out [PostgreSQL](postgres.md) as an alternative. + +The oldest versions that have been tested are MySQL 5.7 and MariaDB 10.6. + +If using MySQL 5.7 or MariaDB 10.6 you may be required to adjust the `explicit_defaults_for_timestamp` setting. This +will be evident when the container starts with an error similar to `Error 1067: Invalid default value for 'exp'`. You +can adjust this setting in the mysql.cnf file like so: + +```cnf +[mysqld] +explicit_defaults_for_timestamp = 1 +``` + +## Configuration + +```yaml +storage: + encryption_key: a_very_important_secret + mysql: + host: 127.0.0.1 + port: 3306 + database: authelia + username: authelia + password: mypassword + timeout: 5s +``` + +## Options + +### encryption_key + +See the [encryption_key docs](introduction.md#encryption_key). + +### host + +{{< confkey type="string" default="localhost" required="no" >}} + +The database server host. + +If utilising an IPv6 literal address it must be enclosed by square brackets and quoted: + +```yaml +host: "[fd00:1111:2222:3333::1]" +``` + +### port + +{{< confkey type="integer" default="3306" required="no" >}} + +The port the database server is listening on. + +### database + +{{< confkey type="string" required="yes" >}} + +The database name on the database server that the assigned [user](#username) has access to for the purpose of +__Authelia__. + +### username + +{{< confkey type="string" required="yes" >}} + +The username paired with the password used to connect to the database. + +### password + +{{< confkey type="string" required="yes" >}} + +The password paired with the username used to connect to the database. Can also be defined using a +[secret](../methods/secrets.md) which is also the recommended way when running as a container. + +We recommend generating a random string with 64 characters or more for this purposes which can be done by following the +[Generating a Random Alphanumeric String](../miscellaneous/guides.md#generating-a-random-alphanumeric-string) +guide. + +### timeout + +{{< confkey type="duration" default="5s" required="no" >}} + +The SQL connection timeout. diff --git a/docs/content/en/configuration/storage/postgres.md b/docs/content/en/configuration/storage/postgres.md new file mode 100644 index 000000000..2dd22859a --- /dev/null +++ b/docs/content/en/configuration/storage/postgres.md @@ -0,0 +1,139 @@ +--- +title: "PostgreSQL" +description: "PostgreSQL Configuration" +lead: "The PostgreSQL storage provider." +date: 2022-03-20T12:52:27+11:00 +draft: false +images: [] +menu: + configuration: + parent: "storage" +weight: 106400 +toc: true +aliases: + - /docs/configuration/storage/postgres.html +--- + +## Version support + +See [PostgreSQL support](https://www.postgresql.org/support/versioning/) for the versions supported by PostgreSQL. We +recommend the *current minor* version of one of the versions supported by PostgreSQL. + +The versions of PostgreSQL that should be supported by Authelia are: + +* 14 +* 13 +* 12 +* 11 +* 10 +* 9.6 + +## Configuration + +```yaml +storage: + encryption_key: a_very_important_secret + postgres: + host: 127.0.0.1 + port: 5432 + database: authelia + schema: public + username: authelia + password: mypassword + ssl: + mode: disable + root_certificate: /path/to/root_cert.pem + certificate: /path/to/cert.pem + key: /path/to/key.pem +``` + +## Options + +### encryption_key + +See the [encryption_key docs](introduction.md#encryption_key). + +### host + +{{< confkey type="string" required="yes" >}} + +The database server host. + +If utilising an IPv6 literal address it must be enclosed by square brackets and quoted: + +```yaml +host: "[fd00:1111:2222:3333::1]" +``` + +### port + +{{< confkey type="integer" default="5432" required="no" >}} + +The port the database server is listening on. + +### database + +{{< confkey type="string" required="yes" >}} + +The database name on the database server that the assigned [user](#username) has access to for the purpose of +__Authelia__. + +### schema + +{{< confkey type="string" default="public" required="no" >}} + +The database schema name to use on the database server that the assigned [user](#username) has access to for the purpose +of __Authelia__. By default this is the public schema. + +### username + +{{< confkey type="string" required="yes" >}} + +The username paired with the password used to connect to the database. + +### password + +{{< confkey type="string" required="yes" >}} + +The password paired with the username used to connect to the database. Can also be defined using a +[secret](../methods/secrets.md) which is also the recommended way when running as a container. + +We recommend generating a random string with 64 characters or more for this purposes which can be done by following the +[Generating a Random Alphanumeric String](../miscellaneous/guides.md#generating-a-random-alphanumeric-string) +guide. + +### timeout + +{{< confkey type="duration" default="5s" required="no" >}} + +The SQL connection timeout. + +### ssl + +#### mode + +{{< confkey type="string" default="disable" required="no" >}} + +SSL mode configures how to handle SSL connections with Postgres. +Valid options are 'disable', 'require', 'verify-ca', or 'verify-full'. +See the [PostgreSQL Documentation](https://www.postgresql.org/docs/12/libpq-ssl.html) +or [pgx - PostgreSQL Driver and Toolkit Documentation](https://pkg.go.dev/github.com/jackc/pgx?tab=doc) +for more information. + +#### root_certificate + +{{< confkey type="string" required="no" >}} + +The optional location of the root certificate file encoded in the PEM format for validation purposes. + +#### certificate + +{{< confkey type="string" required="no" >}} + +The optional location of the certificate file encoded in the PEM format for validation purposes. + +#### key + +{{< confkey type="string" required="no" >}} + +The optional location of the key file encoded in the PEM format for authentication purposes. diff --git a/docs/content/en/configuration/storage/sqlite.md b/docs/content/en/configuration/storage/sqlite.md new file mode 100644 index 000000000..9e54ee04a --- /dev/null +++ b/docs/content/en/configuration/storage/sqlite.md @@ -0,0 +1,44 @@ +--- +title: "SQLite3" +description: "SQLite3 Configuration" +lead: "The SQLite3 storage provider." +date: 2022-03-20T12:52:27+11:00 +draft: false +images: [] +menu: + configuration: + parent: "storage" +weight: 106500 +toc: true +aliases: + - /docs/configuration/storage/sqlite.html +--- + +If you don't have a SQL server, you can use [SQLite](https://en.wikipedia.org/wiki/SQLite). +However please note that this setup will prevent you from running multiple +instances of Authelia since the database will be a local file. + +Use of this storage provider leaves Authelia [stateful](../../overview/authorization/statelessness.md). It's important +in highly available scenarios to use one of the other providers, and we highly recommend it in production environments, +but this requires you setup an external database such as [PostgreSQL](postgres.md). + +## Configuration + +```yaml +storage: + encryption_key: a_very_important_secret + local: + path: /config/db.sqlite3 +``` + +## Options + +### encryption_key + +See the [encryption_key docs](introduction.md#encryption_key). + +### path + +{{< confkey type="string" required="yes" >}} + +The path where the SQLite3 database file will be stored. It will be created if the file does not exist. diff --git a/docs/content/en/configuration/telemetry/_index.md b/docs/content/en/configuration/telemetry/_index.md new file mode 100644 index 000000000..41b578d6e --- /dev/null +++ b/docs/content/en/configuration/telemetry/_index.md @@ -0,0 +1,9 @@ +--- +title: "Telemetry" +description: "Telemetry Configuration" +lead: "" +date: 2022-03-20T12:52:27+11:00 +draft: false +images: [] +weight: 108000 +--- diff --git a/docs/content/en/configuration/telemetry/introduction.md b/docs/content/en/configuration/telemetry/introduction.md new file mode 100644 index 000000000..acbcf9f0b --- /dev/null +++ b/docs/content/en/configuration/telemetry/introduction.md @@ -0,0 +1,20 @@ +--- +title: "Telemetry" +description: "Configuring the Telemetry settings" +lead: "Configuring the Telemetry settings." +date: 2022-03-20T12:52:27+11:00 +draft: false +images: [] +menu: + configuration: + parent: "telemetry" +weight: 108100 +toc: true +--- + +*Authelia* allows collecting telemetry for the purpose of monitoring it. At the present time we only allow collecting +[metrics](./metrics.md). These [metrics](./metrics.md) are stored in memory and must be scraped manually by the +administrator. + +No metrics or telemetry are reported from an *Authelia* binary to any location the administrator doesn't explicitly +configure. This means by default all metrics are disabled. diff --git a/docs/content/en/configuration/telemetry/metrics.md b/docs/content/en/configuration/telemetry/metrics.md new file mode 100644 index 000000000..73a399662 --- /dev/null +++ b/docs/content/en/configuration/telemetry/metrics.md @@ -0,0 +1,45 @@ +--- +title: "Metrics" +description: "Configuring the Metrics Telemetry settings" +lead: "Configuring the Metrics Telemetry settings." +date: 2022-03-20T12:52:27+11:00 +draft: false +images: [] +menu: + configuration: + parent: "telemetry" +weight: 108200 +toc: true +--- + +*Authelia* allows administrators to configure a [Prometheus] Metrics Exporter. + +## Configuration + +```yaml +telemetry: + metrics: + enabled: false + address: "0.0.0.0:9959" +``` + +## Options + +### enabled + +{{< confkey type="boolean" default="false" required="no" >}} + +Determines if the [Prometheus] HTTP Metrics Exporter is enabled. + +### address + +{{< confkey type="address" default="0.0.0.0:9959" required="no" >}} + +Configures the listener address for the [Prometheus] HTTP Metrics Exporter. The address must be a IPv4 or IPv6 address +followed by the port in the `
:` format. + +## See More + +- [Telemetry Reference Documentation](../../reference/guides/metrics.md) + +[Prometheus]: https://prometheus.io/ diff --git a/docs/content/en/contributing/_index.md b/docs/content/en/contributing/_index.md new file mode 100644 index 000000000..3e73d799e --- /dev/null +++ b/docs/content/en/contributing/_index.md @@ -0,0 +1,8 @@ +--- +title : "Contributing" +description: "Contributing Docs" +lead: "" +date: 2022-03-20T12:52:27+11:00 +draft: false +images: [] +--- diff --git a/docs/content/en/contributing/development/_index.md b/docs/content/en/contributing/development/_index.md new file mode 100644 index 000000000..7dd3500ad --- /dev/null +++ b/docs/content/en/contributing/development/_index.md @@ -0,0 +1,9 @@ +--- +title : "Development" +description: "Contributing via Development" +lead: "" +date: 2022-03-20T12:52:27+11:00 +draft: false +images: [] +weight: 200 +--- diff --git a/docs/content/en/contributing/development/build-and-test.md b/docs/content/en/contributing/development/build-and-test.md new file mode 100644 index 000000000..8c0d34735 --- /dev/null +++ b/docs/content/en/contributing/development/build-and-test.md @@ -0,0 +1,104 @@ +--- +title: "Building and Testing" +description: "Building and Testing Authelia." +lead: "This section covers the build process and how to perform tests in development." +date: 2022-05-15T13:52:27+10:00 +draft: false +images: [] +menu: + contributing: + parent: "development" +weight: 240 +toc: true +aliases: + - /docs/contributing/build-and-dev.html +--- + +__Authelia__ is built a [React] frontend user portal bundled in a [Go] application which acts as a basic webserver for +the [React] assets and a dedicated API. + +The GitHub repository comes with a CLI dedicated to developers called +[authelia-scripts](reference-authelia-scripts.md) which can be setup by looking at +[Reference: authelia-scripts](reference-authelia-scripts.md). + +In order to build and contribute to __Authelia__, you need to make sure that you have looked at the +[Environment](environment.md) guide to configure your development environment. + +## Get started + +In order to ease development, __Authelia__ uses the concept of [suites] to run Authelia from source code so that your +patches are included. This is a kind of virtual environment running __Authelia__ in a complete ecosystem +(LDAP, Redis, SQL server). Note that __Authelia__ is hot-reloaded in the environment so that your patches are instantly +included. + +The next command starts the suite called *Standalone*: + +```bash +authelia-scripts suites setup Standalone +``` + +Most of the suites are using docker-compose to bootstrap the environment. Therefore, you can check the logs of all +application by running the following command on the component you want to monitor. + +```bash +docker logs authelia_authelia-backend_1 -f +``` + +Then, edit the code and observe how __Authelia__ is automatically reloaded. + +### Unit tests + +To run the unit tests, run: + +```bash +authelia-scripts unittest +``` + +### Integration tests + +Integration tests are located under the `internal/suites` directory and are based on Selenium. A suite is a combination +of environment and tests. Executing a suite therefore means starting the environment, running the tests and tearing down +the environment. Each step can be run independently: + +```bash +# List the available suites +$ authelia-scripts suites list +Standalone +DuoPush +LDAP +Traefik + +# Start the environment of Standalone suite. +$ authelia-scripts suites setup Standalone + +# Run the tests related to the currently running suite. +$ authelia-scripts suites test + +# Tear down the environment +$ authelia-scripts suites teardown Standalone +``` + +In order to test all suites (approx 30 minutes), you need to make sure there is no currently running sui te and then you +should run: + +```bash +authelia-scripts suites test +``` + +Also, you don't need to start the suite before testing it. Given you're not running any suite, just use the following +command to test the *Standalone* suite. + +```bash +authelia-scripts suites test Standalone +``` + +The suite will be spawned, tests will be run and then the suite will be torn down automatically. + +[suites]: ./integration-suites.md +[React]: https://reactjs.org/ +[go]: https://go.dev/dl/ +[Node.js]: https://nodejs.org/en/download/ +[Docker]: https://docs.docker.com/get-docker/ +[Docker Compose]: https://docs.docker.com/compose/install/ +[golangci-lint]: https://golangci-lint.run/usage/install/ +[goimports-reviser]: https://github.com/incu6us/goimports-reviser#install diff --git a/docs/content/en/contributing/development/environment.md b/docs/content/en/contributing/development/environment.md new file mode 100644 index 000000000..87c94d342 --- /dev/null +++ b/docs/content/en/contributing/development/environment.md @@ -0,0 +1,82 @@ +--- +title: "Environment" +description: "How to configure your development environment." +lead: "This section covers the environment we recommend for development." +date: 2022-05-15T13:52:27+10:00 +draft: false +images: [] +menu: + contributing: + parent: "development" +weight: 220 +toc: true +--- + +__Authelia__ and its development workflow can be tested with [Docker] and [Docker Compose] on Linux. + +## Setup + +In order to build and contribute to __Authelia__, you need to make sure the following are installed in your environment: + +* [go] *(v1.18 or greater)* +* [Docker] +* [Docker Compose] +* [Node.js] *(v16 or greater)* +* [pnpm] + +The additional tools are recommended: + +* [golangci-lint] +* [goimports-reviser] +* [yamllint] +* Either the [VSCodium] or [GoLand] IDE + +## Scripts + +There is a scripting context provided with __Authelia__ which can easily be configured. It allows running integration +[suites] and various other tasks. Read more about it in the [authelia-scripts](reference-authelia-scripts.md) reference +guide. + +## FAQ + +### Do you support development under Windows or OSX? + +At the present time this is not officially supported. Some of the maintainers utilize Windows however running suites +under Windows or OSX is not something that is currently possible to do easily. As such we recommend utilizing Linux. + +### What version of Docker and docker-compose should I use? + +We have no firm recommendations on the version to use but we actively use the latest versions available to us in the +distributions of our choice. As long as it's a modern version it should be sufficient for the development environment. + +### How can I serve my application under example.com? + +Don't worry, you don't need to own the domain `example.com` to test Authelia. Copy the following lines in +your `/etc/hosts`: + +```text +192.168.240.100 home.example.com +192.168.240.100 login.example.com +192.168.240.100 singlefactor.example.com +192.168.240.100 public.example.com +192.168.240.100 secure.example.com +192.168.240.100 mail.example.com +192.168.240.100 mx1.mail.example.com +``` + +The IP address `192.168.240.100` is the IP attributed by [Docker] to the reverse proxy. Once added you can access the +listed subdomains from your browser, and they will be served by the reverse proxy. + +[suites]: ./integration-suites.md +[Buildkite]: https://buildkite.com/ +[React]: https://reactjs.org/ +[go]: https://go.dev/dl/ +[Node.js]: https://nodejs.org/en/download/ +[pnpm]: https://pnpm.io/installation +[Docker]: https://docs.docker.com/get-docker/ +[Docker Compose]: https://docs.docker.com/compose/install/ +[golangci-lint]: https://golangci-lint.run/usage/install/ +[goimports-reviser]: https://github.com/incu6us/goimports-reviser#install +[yamllint]: https://yamllint.readthedocs.io/en/stable/quickstart.html +[VSCodium]: https://vscodium.com/ +[GoLand]: https://www.jetbrains.com/go/ diff --git a/docs/contributing/commitmsg-guidelines.md b/docs/content/en/contributing/development/guidelines-commit-message.md similarity index 62% rename from docs/contributing/commitmsg-guidelines.md rename to docs/content/en/contributing/development/guidelines-commit-message.md index 670734873..0a8ff7dbc 100644 --- a/docs/contributing/commitmsg-guidelines.md +++ b/docs/content/en/contributing/development/guidelines-commit-message.md @@ -1,19 +1,27 @@ --- -layout: default -title: Commit Message Guidelines -parent: Contributing -nav_order: 3 +title: "Commit Message Guidelines" +description: "Authelia Development Commit Message Guidelines" +lead: "This section covers the git commit message guidelines we use for development." +date: 2022-05-15T13:52:27+10:00 +draft: false +images: [] +menu: + contributing: + parent: "development" +weight: 231 +toc: true +aliases: + - /docs/contributing/commitmsg-guidelines.html --- -# Commit Message Guidelines +The reasons for these conventions are as follows: -## The reasons for these conventions: +* simple navigation though git history +* easier to read git history -- simple navigation though and easier to read git history +## Commit Message Format -## Format of the commit message: - -Each commit message consists of a **header**, a **body**, and a **footer**. +Each commit message consists of a __header__, a __body__, and a __footer__. ```bash
@@ -23,19 +31,18 @@ Each commit message consists of a **header**, a **body**, and a **footer**.