dashy/docs/authentication/index.html
2021-08-30 18:12:03 +00:00

20 lines
57 KiB
HTML

<!doctype html>
<html lang="en" dir="ltr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="generator" content="Docusaurus v2.0.0-beta.2">
<title data-react-helmet="true">Authentication | Dashy</title><meta data-react-helmet="true" property="og:url" content="https://dashy.to/docs/authentication"><meta data-react-helmet="true" name="docusaurus_locale" content="en"><meta data-react-helmet="true" name="docusaurus_version" content="current"><meta data-react-helmet="true" name="docusaurus_tag" content="docs-default-current"><meta data-react-helmet="true" property="og:title" content="Authentication | Dashy"><meta data-react-helmet="true" name="description" content="- Basic Auth"><meta data-react-helmet="true" property="og:description" content="- Basic Auth"><link data-react-helmet="true" rel="shortcut icon" href="/img/favicon.ico"><link data-react-helmet="true" rel="canonical" href="https://dashy.to/docs/authentication"><link data-react-helmet="true" rel="alternate" href="https://dashy.to/docs/authentication" hreflang="en"><link data-react-helmet="true" rel="alternate" href="https://dashy.to/docs/authentication" hreflang="x-default"><link rel="stylesheet" href="/assets/css/styles.becbbfc3.css">
<link rel="preload" href="/assets/js/runtime~main.02cab8fc.js" as="script">
<link rel="preload" href="/assets/js/main.dc7bf884.js" as="script">
</head>
<body>
<script>!function(){function t(t){document.documentElement.setAttribute("data-theme",t)}var e=function(){var t=null;try{t=localStorage.getItem("theme")}catch(t){}return t}();t(null!==e?e:"light")}()</script><div id="__docusaurus">
<div><a href="#main" class="skipToContent_1oUP">Skip to main content</a></div><nav class="navbar navbar--fixed-top"><div class="navbar__inner"><div class="navbar__items"><a class="navbar__brand" href="/"><img src="/img/dashy.png" alt="Dashy Logo" class="themedImage_1VuW themedImage--light_3UqQ navbar__logo"><img src="/img/dashy.png" alt="Dashy Logo" class="themedImage_1VuW themedImage--dark_hz6m navbar__logo"><b class="navbar__title">Dashy</b></a></div><div class="navbar__items navbar__items--right"><div class="react-toggle displayOnlyInLargeViewport_GrZ2 react-toggle--disabled"><div class="react-toggle-track" role="button" tabindex="-1"><div class="react-toggle-track-check"><span class="toggle_71bT">🌜</span></div><div class="react-toggle-track-x"><span class="toggle_71bT">🌞</span></div><div class="react-toggle-thumb"></div></div><input type="checkbox" class="react-toggle-screenreader-only" aria-label="Switch between dark and light mode"></div></div></div><div role="presentation" class="navbar-sidebar__backdrop"></div><div class="navbar-sidebar"><div class="navbar-sidebar__brand"><a class="navbar__brand" href="/"><img src="/img/dashy.png" alt="Dashy Logo" class="themedImage_1VuW themedImage--light_3UqQ navbar__logo"><img src="/img/dashy.png" alt="Dashy Logo" class="themedImage_1VuW themedImage--dark_hz6m navbar__logo"><b class="navbar__title">Dashy</b></a></div><div class="navbar-sidebar__items"><div class="menu"><ul class="menu__list"></ul></div></div></div></nav><div class="main-wrapper docs-wrapper doc-page"><div class="docPage_31aa"><aside class="docSidebarContainer_3Kbt"><div class="sidebar_15mo"><nav class="menu menu--responsive thin-scrollbar menu_Bmed menuWithAnnouncementBar_2WvA" aria-label="Sidebar navigation"><button aria-label="Open menu" aria-haspopup="true" class="button button--secondary button--sm menu__button" type="button"><svg class="sidebarMenuIcon_fgN0" width="24" height="24" viewBox="0 0 30 30" aria-hidden="true"><path stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="2" d="M4 7h22M4 15h22M4 23h22"></path></svg></button><ul class="menu__list"><li class="menu__list-item menu__list-item--collapsed"><a class="menu__link menu__link--sublist" href="#!">Running Dashy</a><ul class="menu__list"><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/quick-start">Quick Start</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/deployment">Deployment</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/configuring">Configuring</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/management">Management</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/troubleshooting">Troubleshooting</a></li></ul></li><li class="menu__list-item menu__list-item--collapsed"><a class="menu__link menu__link--sublist" href="#!">Community</a><ul class="menu__list"><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/showcase">User Showcase</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/contributing">Contributing</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/developing">Developing</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/development-guides">Development Guides</a></li></ul></li><li class="menu__list-item"><a class="menu__link menu__link--sublist menu__link--active" href="#!">Feature Docs</a><ul class="menu__list"><li class="menu__list-item"><a class="menu__link" tabindex="0" href="/docs/icons">Icons</a></li><li class="menu__list-item"><a class="menu__link" tabindex="0" href="/docs/theming">Theming</a></li><li class="menu__list-item"><a class="menu__link" tabindex="0" href="/docs/status-indicators">Status Indicators</a></li><li class="menu__list-item"><a aria-current="page" class="menu__link menu__link--active active" tabindex="0" href="/docs/authentication">Authentication</a></li><li class="menu__list-item"><a class="menu__link" tabindex="0" href="/docs/searching">Keyboard Shortcuts</a></li><li class="menu__list-item"><a class="menu__link" tabindex="0" href="/docs/alternate-views">Alternate Views &amp; Opening Methods</a></li><li class="menu__list-item"><a class="menu__link" tabindex="0" href="/docs/multi-language-support">Internationalization</a></li><li class="menu__list-item"><a class="menu__link" tabindex="0" href="/docs/backup-restore">Cloud Backup and Restore</a></li></ul></li><li class="menu__list-item menu__list-item--collapsed"><a class="menu__link menu__link--sublist" href="#!">Misc</a><ul class="menu__list"><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/privacy">Privacy &amp; Security</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/changelog">Changelog</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/license">license</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/code-of-conduct">Contributor Covenant Code of Conduct</a></li></ul></li></ul></nav></div></aside><main class="docMainContainer_3ufF"><div class="container padding-top--md padding-bottom--lg"><div class="row"><div class="col docItemCol_3FnS"><div class="docItemContainer_33ec"><article><div class="markdown"><header><h1 class="h1Heading_27L5">Authentication</h1></header><ul><li><a href="#built-in-auth">Basic Auth</a><ul><li><a href="#setting-up-authentication">Setting Up Authentication</a></li><li><a href="#hash-password">Hash Password</a></li><li><a href="#logging-in-and-out">Logging In and Out</a></li><li><a href="#security">Security</a></li></ul></li><li><a href="#keycloak">Keycloak Auth</a><ul><li><a href="#1-deploy-keycloak">Deploying Keycloak</a></li><li><a href="#2-setup-keycloak-users">Setting up Keycloak</a></li><li><a href="#3-enable-keycloak-in-dashy-config-file">Configuring Dashy for Keycloak</a></li></ul></li><li><a href="#alternative-authentication-methods">Alternative Authentication Methods</a><ul><li><a href="#vpn">VPN</a></li><li><a href="#ip-based-access">IP-Based Access</a></li><li><a href="#web-server-authentication">Web Server Authentication</a></li><li><a href="#oauth-services">OAuth Services</a></li><li><a href="#static-site-hosting-providers">Auth on Cloud Hosting Services</a></li></ul></li></ul><h2><a aria-hidden="true" tabindex="-1" class="anchor enhancedAnchor_2LWZ" id="built-in-auth"></a>Built-In Auth<a class="hash-link" href="#built-in-auth" title="Direct link to heading">#</a></h2><p>Dashy has a basic login page included, and frontend authentication. You can enable this by adding users to the <code>auth</code> section under <code>appConfig</code> in your <code>conf.yml</code>. If this section is not specified, then no authentication will be required to access the app, and it the homepage will resolve to your dashboard.</p><h3><a aria-hidden="true" tabindex="-1" class="anchor enhancedAnchor_2LWZ" id="setting-up-authentication"></a>Setting Up Authentication<a class="hash-link" href="#setting-up-authentication" title="Direct link to heading">#</a></h3><p>The <code>auth</code> property takes an array of users. Each user needs to include a username, hash and optional user type (<code>admin</code> or <code>normal</code>). The hash property is a <a href="https://en.wikipedia.org/wiki/SHA-2" target="_blank" rel="noopener noreferrer">SHA-256 Hash</a> of your desired password. </p><p>For example:</p><div class="codeBlockContainer_K1bP"><div class="codeBlockContent_hGly yaml"><pre tabindex="0" class="prism-code language-yaml codeBlock_23N8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_39YC"><span class="token-line" style="color:#393A34"><span class="token key atrule" style="color:#00a4db">appConfig</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">auth</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">users</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">user</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> alicia</span></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">hash</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> 4D1E58C90B3B94BCAD9848ECCACD6D2A8C9FBC5CA913304BBA5CDEAB36FEEFA3</span></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">type</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> admin</span></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">user</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> bob</span></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">hash</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> 5E884898DA28047151D0E56F8DC6292773603D0D6AABBDD62A11EF721D1542D8</span></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_Ue-o clean-btn">Copy</button></div></div><h3><a aria-hidden="true" tabindex="-1" class="anchor enhancedAnchor_2LWZ" id="hash-password"></a>Hash Password<a class="hash-link" href="#hash-password" title="Direct link to heading">#</a></h3><p>Dashy uses <a href="https://en.wikipedia.org/wiki/Sha-256" target="_blank" rel="noopener noreferrer">SHA-256 Hash</a>, a 64-character string, which you can generate using an online tool, such as <a href="https://passwordsgenerator.net/sha256-hash-generator/" target="_blank" rel="noopener noreferrer">this one</a> or <a href="https://gchq.github.io/CyberChef/" target="_blank" rel="noopener noreferrer">CyberChef</a> (which can be self-hosted/ ran locally).</p><p>A hash is a one-way cryptographic function, meaning that it is easy to generate a hash for a given password, but very hard to determine the original password for a given hash. This means, that so long as your password is long, strong and unique, it is safe to store it&#x27;s hash in the clear. Having said that, you should never reuse passwords, hashes can be cracked by iterating over known password lists, generating a hash of each.</p><h3><a aria-hidden="true" tabindex="-1" class="anchor enhancedAnchor_2LWZ" id="logging-in-and-out"></a>Logging In and Out<a class="hash-link" href="#logging-in-and-out" title="Direct link to heading">#</a></h3><p>Once authentication is enabled, so long as there is no valid token in cookie storage, the application will redirect the user to the login page. When the user enters credentials in the login page, they will be checked, and if valid, then a token will be generated, and they can be redirected to the home page. If credentials are invalid, then an error message will be shown, and they will remain on the login page. Once in the application, to log out the user can click the logout button (in the top-right), which will clear cookie storage, causing them to be redirected back to the login page.</p><h3><a aria-hidden="true" tabindex="-1" class="anchor enhancedAnchor_2LWZ" id="enabling-guest-access"></a>Enabling Guest Access<a class="hash-link" href="#enabling-guest-access" title="Direct link to heading">#</a></h3><p>With authentication setup, by default no access is allowed to your dashboard without first logging in with valid credentials. Guest mode can be enabled to allow for read-only access to a secured dashboard by any user, without the need to log in. A guest user cannot write any changes to the config file, but can apply modifications locally (stored in their browser). You can enable guest access, by setting <code>appConfig.enableGuestAccess: true</code>.</p><h3><a aria-hidden="true" tabindex="-1" class="anchor enhancedAnchor_2LWZ" id="granular-access"></a>Granular Access<a class="hash-link" href="#granular-access" title="Direct link to heading">#</a></h3><p>You can use the following properties to make certain sections only visible to some users, or hide sections from guests.</p><ul><li><code>hideForUsers</code> - Section will be visible to all users, except for those specified in this list</li><li><code>showForUsers</code> - Section will be hidden from all users, except for those specified in this list</li><li><code>hideForGuests</code> - Section will be visible for logged in users, but not for guests</li></ul><p>For Example:</p><div class="codeBlockContainer_K1bP"><div class="codeBlockContent_hGly yaml"><pre tabindex="0" class="prism-code language-yaml codeBlock_23N8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_39YC"><span class="token-line" style="color:#393A34"><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Code Analysis &amp; Monitoring</span></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">icon</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> fas fa</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">code</span></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">displayData</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">cols</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2</span><span class="token plain"></span></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">hideForUsers</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">alicia</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> bob</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">items</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">...</span></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_Ue-o clean-btn">Copy</button></div></div><div class="codeBlockContainer_K1bP"><div class="codeBlockContent_hGly yaml"><pre tabindex="0" class="prism-code language-yaml codeBlock_23N8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_39YC"><span class="token-line" style="color:#393A34"><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Deployment Pipelines</span></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">icon</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> fas fa</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">rocket</span></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">displayData</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">hideForGuests</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean important" style="color:#36acaa">true</span><span class="token plain"></span></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">items</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">...</span></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_Ue-o clean-btn">Copy</button></div></div><h3><a aria-hidden="true" tabindex="-1" class="anchor enhancedAnchor_2LWZ" id="security"></a>Security<a class="hash-link" href="#security" title="Direct link to heading">#</a></h3><p>Since all authentication is happening entirely on the client-side, it is vulnerable to manipulation by an adversary. An attacker could look at the source code, find the function used generate the auth token, then decode the minified JavaScript to find the hash, and manually generate a token using it, then just insert that value as a cookie using the console, and become a logged in user. Therefore, if you need secure authentication for your app, it is strongly recommended to implement this using your web server, or use a VPN to control access to Dashy. The purpose of the login page is merely to prevent immediate unauthorized access to your homepage.</p><p>Addressing this is on the todo list, and there are several potential solutions:</p><ol><li>Encrypt all site data against the users password, so that an attacker can not physically access any data without the correct decryption key</li><li>Use a backend service to handle authentication and configuration, with no user data returned from the server until the correct credentials are provided. However, this would require either Dashy to be run using it&#x27;s Node.js server, or the use of an external service</li><li><del>Implement authentication using a self-hosted identity management solution, such as <a href="https://www.keycloak.org/securing-apps/vue" target="_blank" rel="noopener noreferrer">Keycloak for Vue</a></del> <strong>This is now implemented, and released in PR #174 of V 1.6.5!</strong></li></ol><p><strong><a href="#">⬆️ Back to Top</a></strong></p><hr><h2><a aria-hidden="true" tabindex="-1" class="anchor enhancedAnchor_2LWZ" id="keycloak"></a>Keycloak<a class="hash-link" href="#keycloak" title="Direct link to heading">#</a></h2><p>Dashy also supports using a <a href="https://www.keycloak.org/" target="_blank" rel="noopener noreferrer">Keycloack</a> authentication server. The setup for this is a bit more involved, but it gives you greater security overall, useful for if your instance is exposed to the internet.</p><p><a href="https://www.keycloak.org/about.html" target="_blank" rel="noopener noreferrer">Keycloak</a> is a Java-based <a href="https://github.com/keycloak/keycloak" target="_blank" rel="noopener noreferrer">open source</a>, high-performance, secure authentication system, supported by <a href="https://www.redhat.com/en" target="_blank" rel="noopener noreferrer">RedHad</a>. It is easy to setup (<a href="https://quay.io/repository/keycloak/keycloak" target="_blank" rel="noopener noreferrer">with Docker</a>), and enables you to secure multiple self-hosted applications with single-sign on using standard protocols (OpenID Connect, OAuth 2.0, SAML 2.0 and social login). It&#x27;s also very customizable, you can write or use custom <a href="https://wjw465150.gitbooks.io/keycloak-documentation/content/server_development/topics/themes.html" target="_blank" rel="noopener noreferrer">themes</a>, <a href="https://www.keycloak.org/extensions.html" target="_blank" rel="noopener noreferrer">plugins</a>, <a href="https://wjw465150.gitbooks.io/keycloak-documentation/content/server_admin/topics/authentication/password-policies.html" target="_blank" rel="noopener noreferrer">password policies</a> and more.
The following guide will walk you through setting up Keycloak with Dashy. If you already have a Keycloak instance configured, then skip to Step 3.</p><h3><a aria-hidden="true" tabindex="-1" class="anchor enhancedAnchor_2LWZ" id="1-deploy-keycloak"></a>1. Deploy Keycloak<a class="hash-link" href="#1-deploy-keycloak" title="Direct link to heading">#</a></h3><p>First thing to do is to spin up a new instance of Keycloak. You will need <a href="https://docs.docker.com/engine/install/" target="_blank" rel="noopener noreferrer">Docker installed</a>, and can then choose a tag, and pull the container from <a href="https://quay.io/repository/keycloak/keycloak" target="_blank" rel="noopener noreferrer">quay.io/keycloak/keycloak</a></p><p>Use the following run command, replacing the attributes (default credentials, port and name), or incorporate this into your docker-compose file.</p><div class="codeBlockContainer_K1bP"><div class="codeBlockContent_hGly bash"><pre tabindex="0" class="prism-code language-bash codeBlock_23N8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_39YC"><span class="token-line" style="color:#393A34"><span class="token plain">docker run -d </span><span class="token punctuation" style="color:#393A34">\</span><span class="token plain"></span></span><span class="token-line" style="color:#393A34"><span class="token plain"> -p </span><span class="token number" style="color:#36acaa">8081</span><span class="token plain">:8080 </span><span class="token punctuation" style="color:#393A34">\</span><span class="token plain"></span></span><span class="token-line" style="color:#393A34"><span class="token plain"> --name auth-server </span><span class="token punctuation" style="color:#393A34">\</span><span class="token plain"></span></span><span class="token-line" style="color:#393A34"><span class="token plain"> -e </span><span class="token assign-left variable" style="color:#36acaa">KEYCLOAK_USER</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">admin </span><span class="token punctuation" style="color:#393A34">\</span><span class="token plain"></span></span><span class="token-line" style="color:#393A34"><span class="token plain"> -e </span><span class="token assign-left variable" style="color:#36acaa">KEYCLOAK_PASSWORD</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">admin </span><span class="token punctuation" style="color:#393A34">\</span><span class="token plain"></span></span><span class="token-line" style="color:#393A34"><span class="token plain"> quay.io/keycloak/keycloak:15.0.2</span></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_Ue-o clean-btn">Copy</button></div></div><p>If you need to pull from DockerHub, a non-official image is available <a href="https://registry.hub.docker.com/r/jboss/keycloak" target="_blank" rel="noopener noreferrer">here</a>. Or if you would prefer not to use Docker, you can also directly install Keycloak from source, following <a href="https://www.keycloak.org/docs/latest/getting_started/index.html" target="_blank" rel="noopener noreferrer">this guide</a>.</p><p>You should now be able to access the Keycloak web interface, using the port specified above (e.g. <code>http://127.0.0.1:8081</code>), login with the default credentials, and when prompted create a new password.</p><h3><a aria-hidden="true" tabindex="-1" class="anchor enhancedAnchor_2LWZ" id="2-setup-keycloak-users"></a>2. Setup Keycloak Users<a class="hash-link" href="#2-setup-keycloak-users" title="Direct link to heading">#</a></h3><p>Before we can use Keycloak, we must first set it up with some users. Keycloak uses Realms (similar to tenants) to create isolated groups of users. You must create a Realm before you will be able to add your first user. </p><ol><li>Head over to the admin console</li><li>In the top-left corner there is a dropdown called &#x27;Master&#x27;, hover over it and then click &#x27;Add Realm&#x27;</li><li>Give your realm a name, and hit &#x27;Create&#x27;</li></ol><p>You can now create your first user.</p><ol><li>In the left-hand menu, click &#x27;Users&#x27;, then &#x27;Add User&#x27;</li><li>Fill in the form, including username and hit &#x27;Save&#x27;</li><li>Under the &#x27;Credentials&#x27; tab, give the new user an initial password. They will be prompted to change this after first login</li></ol><p>The last thing we need to do in the Keycloak admin console is to create a new client</p><ol><li>Within your new realm, navigate to &#x27;Clients&#x27; on the left-hand side, then click &#x27;Create&#x27; in the top-right</li><li>Choose a &#x27;Client ID&#x27;, set &#x27;Client Protocol&#x27; to &#x27;openid-connect&#x27;, and for &#x27;Valid Redirect URIs&#x27; put a URL pattern to where you&#x27;re hosting Dashy (if you&#x27;re just testing locally, then * is fine), and do the same for the &#x27;Web Origins&#x27; field</li><li>Make note of your client-id, and click &#x27;Save&#x27;</li></ol><h3><a aria-hidden="true" tabindex="-1" class="anchor enhancedAnchor_2LWZ" id="3-enable-keycloak-in-dashy-config-file"></a>3. Enable Keycloak in Dashy Config File<a class="hash-link" href="#3-enable-keycloak-in-dashy-config-file" title="Direct link to heading">#</a></h3><p>Now that your Keycloak instance is up and running, all that&#x27;s left to do is to configure Dashy to use it. Under <code>appConfig</code>, set <code>auth.enableKeycloak: true</code>, then fill in the details in <code>auth.keycloak</code>, including: <code>serverUrl</code> - the URL where your Keycloak instance is hosted, <code>realm</code> - the name you gave your Realm, and <code>clientId</code> - the Client ID you chose.
For example:</p><div class="codeBlockContainer_K1bP"><div class="codeBlockContent_hGly yaml"><pre tabindex="0" class="prism-code language-yaml codeBlock_23N8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_39YC"><span class="token-line" style="color:#393A34"><span class="token key atrule" style="color:#00a4db">appConfig</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">...</span><span class="token plain"></span></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">auth</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">enableKeycloak</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean important" style="color:#36acaa">true</span><span class="token plain"></span></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">keycloak</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">serverUrl</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&#x27;http://localhost:8081&#x27;</span><span class="token plain"></span></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">realm</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&#x27;alicia-homelab&#x27;</span><span class="token plain"></span></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">clientId</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&#x27;dashy&#x27;</span></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_Ue-o clean-btn">Copy</button></div></div><p>Your app is now secured :) When you load Dashy, it will redirect to your Keycloak login page, and any user without valid credentials will be prevented from accessing your dashboard.</p><p>From within the Keycloak console, you can then configure things like user permissions, time outs, password policies, access, etc. You can also backup your full Keycloak config, and it is recommended to do this, along with your Dashy config. You can spin up both Dashy and Keycloak simultaneously and restore both applications configs using a <code>docker-compose.yml</code> file, and this is recommended.</p><hr><h2><a aria-hidden="true" tabindex="-1" class="anchor enhancedAnchor_2LWZ" id="alternative-authentication-methods"></a>Alternative Authentication Methods<a class="hash-link" href="#alternative-authentication-methods" title="Direct link to heading">#</a></h2><p>If you are self-hosting Dashy, and require secure authentication to prevent unauthorized access, then you can either use Keycloak, or one of the following options:</p><ul><li><a href="#authentication-server">Authentication Server</a> - Put Dashy behind a self-hosted auth server</li><li><a href="#vpn">VPN</a> - Use a VPN to tunnel into the network where Dashy is running</li><li><a href="#ip-based-access">IP-Based Access</a> - Disallow access from all IP addresses, except your own</li><li><a href="#web-server-authentication">Web Server Authentication</a> - Enable user control within your web server or proxy</li><li><a href="#oauth-services">OAuth Services</a> - Implement a user management system using a cloud provider</li><li><a href="#static-site-hosting-providers">Password Protection (for cloud providers)</a> - Enable password-protection on your site</li></ul><h3><a aria-hidden="true" tabindex="-1" class="anchor enhancedAnchor_2LWZ" id="authentication-server"></a>Authentication Server<a class="hash-link" href="#authentication-server" title="Direct link to heading">#</a></h3><h5><a aria-hidden="true" tabindex="-1" class="anchor enhancedAnchor_2LWZ" id="authelia"></a>Authelia<a class="hash-link" href="#authelia" title="Direct link to heading">#</a></h5><p><a href="https://www.authelia.com/" target="_blank" rel="noopener noreferrer">Authelia</a> is an open-source full-featured authentication server, which can be self-hosted and either on bare metal, in a Docker container or in a Kubernetes cluster. It allows for fine-grained access control rules based on IP, path, users etc, and supports 2FA, simple password access or bypass policies for your domains. </p><ul><li><code>git clone https://github.com/authelia/authelia.git</code></li><li><code>cd authelia/examples/compose/lite</code></li><li>Modify the <code>users_database.yml</code> the default username and password is authelia</li><li>Modify the <code>configuration.yml</code> and <code>docker-compose.yml</code> with your respective domains and secrets</li><li><code>docker-compose up -d</code></li></ul><p>For more information, see the <a href="https://www.authelia.com/docs/" target="_blank" rel="noopener noreferrer">Authelia docs</a></p><h3><a aria-hidden="true" tabindex="-1" class="anchor enhancedAnchor_2LWZ" id="vpn"></a>VPN<a class="hash-link" href="#vpn" title="Direct link to heading">#</a></h3><p>A catch-all solution to accessing services running from your home network remotely is to use a VPN. It means you do not need to worry about implementing complex authentication rules, or trusting the login implementation of individual applications. However it can be inconvenient to use on a day-to-day basis, and some public and corporate WiFi block VPN connections. Two popular VPN protocols are <a href="https://openvpn.net/" target="_blank" rel="noopener noreferrer">OpenVPN</a> and <a href="https://www.wireguard.com/" target="_blank" rel="noopener noreferrer">WireGuard</a></p><h3><a aria-hidden="true" tabindex="-1" class="anchor enhancedAnchor_2LWZ" id="ip-based-access"></a>IP-Based Access<a class="hash-link" href="#ip-based-access" title="Direct link to heading">#</a></h3><p>If you have a static IP or use a VPN to access your running services, then you can use conditional access to block access to Dashy from everyone except users of your pre-defined IP address. This feature is offered by most cloud providers, and supported by most web servers.</p><h5><a aria-hidden="true" tabindex="-1" class="anchor enhancedAnchor_2LWZ" id="apache"></a>Apache<a class="hash-link" href="#apache" title="Direct link to heading">#</a></h5><p>In Apache, this is configured in your <code>.htaccess</code> file in Dashy&#x27;s root folder, and should look something like:</p><div class="codeBlockContainer_K1bP"><div class="codeBlockContent_hGly"><pre tabindex="0" class="prism-code language-undefined codeBlock_23N8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_39YC"><span class="token-line" style="color:#393A34"><span class="token plain">Order Deny,Allow</span></span><span class="token-line" style="color:#393A34"><span class="token plain">Deny from all</span></span><span class="token-line" style="color:#393A34"><span class="token plain">Allow from [your-ip]</span></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_Ue-o clean-btn">Copy</button></div></div><h5><a aria-hidden="true" tabindex="-1" class="anchor enhancedAnchor_2LWZ" id="nginx"></a>NGINX<a class="hash-link" href="#nginx" title="Direct link to heading">#</a></h5><p>In NGINX you can specify <a href="https://docs.nginx.com/nginx/admin-guide/security-controls/controlling-access-proxied-http/" target="_blank" rel="noopener noreferrer">control access</a> rules for a given site in your <code>nginx.conf</code> or hosts file. For example:</p><div class="codeBlockContainer_K1bP"><div class="codeBlockContent_hGly"><pre tabindex="0" class="prism-code language-undefined codeBlock_23N8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_39YC"><span class="token-line" style="color:#393A34"><span class="token plain">server {</span></span><span class="token-line" style="color:#393A34"><span class="token plain"> listen 80;</span></span><span class="token-line" style="color:#393A34"><span class="token plain"> server_name www.dashy.example.com;</span></span><span class="token-line" style="color:#393A34"><span class="token plain"> location / {</span></span><span class="token-line" style="color:#393A34"><span class="token plain"> root /path/to/dashy/;</span></span><span class="token-line" style="color:#393A34"><span class="token plain"> passenger_enabled on;</span></span><span class="token-line" style="color:#393A34"><span class="token plain"> allow [your-ip];</span></span><span class="token-line" style="color:#393A34"><span class="token plain"> deny all;</span></span><span class="token-line" style="color:#393A34"><span class="token plain"> }</span></span><span class="token-line" style="color:#393A34"><span class="token plain"> }</span></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_Ue-o clean-btn">Copy</button></div></div><h5><a aria-hidden="true" tabindex="-1" class="anchor enhancedAnchor_2LWZ" id="caddy"></a>Caddy<a class="hash-link" href="#caddy" title="Direct link to heading">#</a></h5><p>In Caddy, <a href="https://caddyserver.com/docs/caddyfile/matchers" target="_blank" rel="noopener noreferrer">Request Matchers</a> can be used to filter requests </p><div class="codeBlockContainer_K1bP"><div class="codeBlockContent_hGly"><pre tabindex="0" class="prism-code language-undefined codeBlock_23N8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_39YC"><span class="token-line" style="color:#393A34"><span class="token plain">dashy.site {</span></span><span class="token-line" style="color:#393A34"><span class="token plain"> @public_networks not remote_ip [your-ip]</span></span><span class="token-line" style="color:#393A34"><span class="token plain"> respond @public_networks &quot;Access denied&quot; 403</span></span><span class="token-line" style="color:#393A34"><span class="token plain">}</span></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_Ue-o clean-btn">Copy</button></div></div><h3><a aria-hidden="true" tabindex="-1" class="anchor enhancedAnchor_2LWZ" id="web-server-authentication"></a>Web Server Authentication<a class="hash-link" href="#web-server-authentication" title="Direct link to heading">#</a></h3><p>Most web servers make password protecting certain apps very easy. Note that you should also set up HTTPS and have a valid certificate in order for this to be secure.</p><h5><a aria-hidden="true" tabindex="-1" class="anchor enhancedAnchor_2LWZ" id="apache-1"></a>Apache<a class="hash-link" href="#apache-1" title="Direct link to heading">#</a></h5><p>First crate a <code>.htaccess</code> file in Dashy&#x27;s route directory. Specify the auth type and path to where you want to store the password file (usually the same folder). For example:</p><div class="codeBlockContainer_K1bP"><div class="codeBlockContent_hGly"><pre tabindex="0" class="prism-code language-undefined codeBlock_23N8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_39YC"><span class="token-line" style="color:#393A34"><span class="token plain">AuthType Basic </span></span><span class="token-line" style="color:#393A34"><span class="token plain">AuthName &quot;Please Sign into Dashy&quot; </span></span><span class="token-line" style="color:#393A34"><span class="token plain">AuthUserFile /path/dashy/.htpasswd </span></span><span class="token-line" style="color:#393A34"><span class="token plain">require valid-user</span></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_Ue-o clean-btn">Copy</button></div></div><p>Then create a <code>.htpasswd</code> file in the same directory. List users and their hashed passwords here, with one user on each line, and a colon between username and password (e.g. <code>[username]:[hashed-password]</code>). You will need to generate an MD5 hash of your desired password, this can be done with an <a href="https://www.web2generators.com/apache-tools/htpasswd-generator" target="_blank" rel="noopener noreferrer">online tool</a>. Your file will look something like:</p><div class="codeBlockContainer_K1bP"><div class="codeBlockContent_hGly"><pre tabindex="0" class="prism-code language-undefined codeBlock_23N8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_39YC"><span class="token-line" style="color:#393A34"><span class="token plain">alicia:$apr1$jv0spemw$RzOX5/GgY69JMkgV6u16l0</span></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_Ue-o clean-btn">Copy</button></div></div><h5><a aria-hidden="true" tabindex="-1" class="anchor enhancedAnchor_2LWZ" id="nginx-1"></a>NGINX<a class="hash-link" href="#nginx-1" title="Direct link to heading">#</a></h5><p>NGINX has an <a href="https://nginx.org/en/docs/http/ngx_http_auth_basic_module.html" target="_blank" rel="noopener noreferrer">authentication module</a> which can be used to add passwords to given sites, and is fairly simple to set up. Similar to above, you will need to create a <code>.htpasswd</code> file. Then just enable auth and specify the path to that file, for example:</p><div class="codeBlockContainer_K1bP"><div class="codeBlockContent_hGly"><pre tabindex="0" class="prism-code language-undefined codeBlock_23N8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_39YC"><span class="token-line" style="color:#393A34"><span class="token plain">location / {</span></span><span class="token-line" style="color:#393A34"><span class="token plain"> auth_basic &quot;closed site&quot;;</span></span><span class="token-line" style="color:#393A34"><span class="token plain"> auth_basic_user_file conf/htpasswd;</span></span><span class="token-line" style="color:#393A34"><span class="token plain">}</span></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_Ue-o clean-btn">Copy</button></div></div><h5><a aria-hidden="true" tabindex="-1" class="anchor enhancedAnchor_2LWZ" id="caddy-1"></a>Caddy<a class="hash-link" href="#caddy-1" title="Direct link to heading">#</a></h5><p>Caddy has a <a href="https://caddyserver.com/docs/caddyfile/directives/basicauth" target="_blank" rel="noopener noreferrer">basic-auth</a> directive, where you specify a username and hash. The password hash needs to be base-64 encoded, the <a href="https://caddyserver.com/docs/command-line#caddy-hash-password" target="_blank" rel="noopener noreferrer"><code>caddy hash-password</code></a> command can help with this. For example:</p><div class="codeBlockContainer_K1bP"><div class="codeBlockContent_hGly"><pre tabindex="0" class="prism-code language-undefined codeBlock_23N8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_39YC"><span class="token-line" style="color:#393A34"><span class="token plain">basicauth /secret/* {</span></span><span class="token-line" style="color:#393A34"><span class="token plain"> alicia JDJhJDEwJEVCNmdaNEg2Ti5iejRMYkF3MFZhZ3VtV3E1SzBWZEZ5Q3VWc0tzOEJwZE9TaFlZdEVkZDhX</span></span><span class="token-line" style="color:#393A34"><span class="token plain">}</span></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_Ue-o clean-btn">Copy</button></div></div><p>For more info about implementing a single sign on for all your apps with Caddy, see <a href="https://joshstrange.com/securing-your-self-hosted-apps-with-single-signon/" target="_blank" rel="noopener noreferrer">this tutorial</a></p><h5><a aria-hidden="true" tabindex="-1" class="anchor enhancedAnchor_2LWZ" id="lighttpd"></a>Lighttpd<a class="hash-link" href="#lighttpd" title="Direct link to heading">#</a></h5><p>You can use the <a href="https://doc.lighttpd.net/lighttpd2/mod_auth.html" target="_blank" rel="noopener noreferrer">mod_auth</a> module to secure your site with Lighttpd. Like with Apache, you need to first create a password file listing your usersnames and hashed passwords, but in Lighttpd, it&#x27;s usually called <code>.lighttpdpassword</code>.</p><p>Then in your <code>lighttpd.conf</code> file (usually in the <code>/etc/lighttpd/</code> directory), load in the mod_auth module, and configure it&#x27;s directives. For example:</p><div class="codeBlockContainer_K1bP"><div class="codeBlockContent_hGly"><pre tabindex="0" class="prism-code language-undefined codeBlock_23N8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_39YC"><span class="token-line" style="color:#393A34"><span class="token plain">server.modules += ( &quot;mod_auth&quot; )</span></span><span class="token-line" style="color:#393A34"><span class="token plain">auth.debug = 2</span></span><span class="token-line" style="color:#393A34"><span class="token plain">auth.backend = &quot;plain&quot;</span></span><span class="token-line" style="color:#393A34"><span class="token plain">auth.backend.plain.userfile = &quot;/home/lighttpd/.lighttpdpassword&quot;</span></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block">
</span></span><span class="token-line" style="color:#393A34"><span class="token plain">$HTTP[&quot;host&quot;] == &quot;dashy.my-domain.net&quot; {</span></span><span class="token-line" style="color:#393A34"><span class="token plain"> server.document-root = &quot;/home/lighttpd/dashy.my-domain.net/http&quot;</span></span><span class="token-line" style="color:#393A34"><span class="token plain"> server.errorlog = &quot;/var/log/lighttpd/dashy.my-domain.net/error.log&quot;</span></span><span class="token-line" style="color:#393A34"><span class="token plain"> accesslog.filename = &quot;/var/log/lighttpd/dashy.my-domain.net/access.log&quot;</span></span><span class="token-line" style="color:#393A34"><span class="token plain"> auth.require = (</span></span><span class="token-line" style="color:#393A34"><span class="token plain"> &quot;/docs/&quot; =&gt; (</span></span><span class="token-line" style="color:#393A34"><span class="token plain"> &quot;method&quot; =&gt; &quot;basic&quot;,</span></span><span class="token-line" style="color:#393A34"><span class="token plain"> &quot;realm&quot; =&gt; &quot;Password protected area&quot;,</span></span><span class="token-line" style="color:#393A34"><span class="token plain"> &quot;require&quot; =&gt; &quot;user=alicia&quot;</span></span><span class="token-line" style="color:#393A34"><span class="token plain"> )</span></span><span class="token-line" style="color:#393A34"><span class="token plain"> )</span></span><span class="token-line" style="color:#393A34"><span class="token plain">}</span></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_Ue-o clean-btn">Copy</button></div></div><p>Restart your web server for changes to take effect.</p><h3><a aria-hidden="true" tabindex="-1" class="anchor enhancedAnchor_2LWZ" id="oauth-services"></a>OAuth Services<a class="hash-link" href="#oauth-services" title="Direct link to heading">#</a></h3><p>There are also authentication services, such as <a href="https://www.ory.sh/" target="_blank" rel="noopener noreferrer">Ory.sh</a>, <a href="https://developer.okta.com/" target="_blank" rel="noopener noreferrer">Okta</a>, <a href="https://auth0.com/" target="_blank" rel="noopener noreferrer">Auth0</a>, <a href="https://firebase.google.com/docs/auth/" target="_blank" rel="noopener noreferrer">Firebase</a>. Implementing one of these solutions would involve some changes to the <a href="https://github.com/Lissy93/dashy/blob/master/src/utils/Auth.js" target="_blank" rel="noopener noreferrer"><code>Auth.js</code></a> file, but should be fairly straight forward.</p><h3><a aria-hidden="true" tabindex="-1" class="anchor enhancedAnchor_2LWZ" id="static-site-hosting-providers"></a>Static Site Hosting Providers<a class="hash-link" href="#static-site-hosting-providers" title="Direct link to heading">#</a></h3><p>If you are hosting Dashy on a cloud platform, you will probably find that it has built-in support for password protected access to web apps. For more info, see the relevant docs for your provider, for example: <a href="https://docs.netlify.com/visitor-access/password-protection/" target="_blank" rel="noopener noreferrer">Netlify Password Protection</a>, <a href="https://www.cloudflare.com/teams/access/" target="_blank" rel="noopener noreferrer">Cloudflare Access</a>, <a href="https://aws.amazon.com/cognito/" target="_blank" rel="noopener noreferrer">AWS Cognito</a>, <a href="https://docs.microsoft.com/en-us/azure/app-service/scenario-secure-app-authentication-app-service" target="_blank" rel="noopener noreferrer">Azure Authentication</a> and <a href="https://vercel.com/docs/platform/projects#password-protection" target="_blank" rel="noopener noreferrer">Vercel Password Protection</a>.</p><p><strong><a href="#">⬆️ Back to Top</a></strong></p></div><footer class="row docusaurus-mt-lg"><div class="col"><a href="https://github.com/Lissy93/dashy/edit/gh-pages/docs/docs/authentication.md" target="_blank" rel="noreferrer noopener"><svg fill="currentColor" height="20" width="20" viewBox="0 0 40 40" class="iconEdit_2_ui" aria-hidden="true"><g><path d="m34.5 11.7l-3 3.1-6.3-6.3 3.1-3q0.5-0.5 1.2-0.5t1.1 0.5l3.9 3.9q0.5 0.4 0.5 1.1t-0.5 1.2z m-29.5 17.1l18.4-18.5 6.3 6.3-18.4 18.4h-6.3v-6.2z"></path></g></svg>Edit this page</a></div><div class="col lastUpdated_3DPF"></div></footer></article><nav class="pagination-nav docusaurus-mt-lg" aria-label="Docs pages navigation"><div class="pagination-nav__item"><a class="pagination-nav__link" href="/docs/status-indicators"><div class="pagination-nav__sublabel">Previous</div><div class="pagination-nav__label">« Status Indicators</div></a></div><div class="pagination-nav__item pagination-nav__item--next"><a class="pagination-nav__link" href="/docs/searching"><div class="pagination-nav__sublabel">Next</div><div class="pagination-nav__label">Keyboard Shortcuts »</div></a></div></nav></div></div><div class="col col--3"><div class="tableOfContents_35-E thin-scrollbar"><ul class="table-of-contents table-of-contents__left-border"><li><a href="#built-in-auth" class="table-of-contents__link">Built-In Auth</a><ul><li><a href="#setting-up-authentication" class="table-of-contents__link">Setting Up Authentication</a></li><li><a href="#hash-password" class="table-of-contents__link">Hash Password</a></li><li><a href="#logging-in-and-out" class="table-of-contents__link">Logging In and Out</a></li><li><a href="#enabling-guest-access" class="table-of-contents__link">Enabling Guest Access</a></li><li><a href="#granular-access" class="table-of-contents__link">Granular Access</a></li><li><a href="#security" class="table-of-contents__link">Security</a></li></ul></li><li><a href="#keycloak" class="table-of-contents__link">Keycloak</a><ul><li><a href="#1-deploy-keycloak" class="table-of-contents__link">1. Deploy Keycloak</a></li><li><a href="#2-setup-keycloak-users" class="table-of-contents__link">2. Setup Keycloak Users</a></li><li><a href="#3-enable-keycloak-in-dashy-config-file" class="table-of-contents__link">3. Enable Keycloak in Dashy Config File</a></li></ul></li><li><a href="#alternative-authentication-methods" class="table-of-contents__link">Alternative Authentication Methods</a><ul><li><a href="#authentication-server" class="table-of-contents__link">Authentication Server</a></li><li><a href="#vpn" class="table-of-contents__link">VPN</a></li><li><a href="#ip-based-access" class="table-of-contents__link">IP-Based Access</a></li><li><a href="#web-server-authentication" class="table-of-contents__link">Web Server Authentication</a></li><li><a href="#oauth-services" class="table-of-contents__link">OAuth Services</a></li><li><a href="#static-site-hosting-providers" class="table-of-contents__link">Static Site Hosting Providers</a></li></ul></li></ul></div></div></div></div></main></div></div><footer class="footer footer--dark"><div class="container"><div class="row footer__links"><div class="col footer__col"><div class="footer__title">Intro</div><ul class="footer__items"><li class="footer__item"><a href="https://github.com/lissy93/dashy" target="_blank" rel="noopener noreferrer" class="footer__link-item">GitHub</a></li><li class="footer__item"><a href="https://demo.dashy.to" target="_blank" rel="noopener noreferrer" class="footer__link-item">Live Demo</a></li><li class="footer__item"><a class="footer__link-item" href="/docs/quick-start">Quick Start</a></li><li class="footer__item"><a class="footer__link-item" href="/docs">Documentation</a></li></ul></div><div class="col footer__col"><div class="footer__title">Setup Guide</div><ul class="footer__items"><li class="footer__item"><a class="footer__link-item" href="/docs/deployment">Deploying</a></li><li class="footer__item"><a class="footer__link-item" href="/docs/configuring">Configuring</a></li><li class="footer__item"><a class="footer__link-item" href="/docs/management">Management</a></li><li class="footer__item"><a class="footer__link-item" href="/docs/troubleshooting">Troubleshooting</a></li></ul></div><div class="col footer__col"><div class="footer__title">Feature Docs Pt 1</div><ul class="footer__items"><li class="footer__item"><a class="footer__link-item" href="/docs/authentication">Authentication</a></li><li class="footer__item"><a class="footer__link-item" href="/docs/alternate-views">Alternate Views</a></li><li class="footer__item"><a class="footer__link-item" href="/docs/backup-restore">Backup &amp; Restore</a></li><li class="footer__item"><a class="footer__link-item" href="/docs/icons">Icons</a></li></ul></div><div class="col footer__col"><div class="footer__title">Feature Docs Pt 2</div><ul class="footer__items"><li class="footer__item"><a class="footer__link-item" href="/docs/multi-language-support">Language Switching</a></li><li class="footer__item"><a class="footer__link-item" href="/docs/status-indicators">Status Indicators</a></li><li class="footer__item"><a class="footer__link-item" href="/docs/searching">Searching &amp; Shortcuts</a></li><li class="footer__item"><a class="footer__link-item" href="/docs/theming">Theming</a></li></ul></div><div class="col footer__col"><div class="footer__title">Community</div><ul class="footer__items"><li class="footer__item"><a class="footer__link-item" href="/docs/developing">Developing</a></li><li class="footer__item"><a class="footer__link-item" href="/docs/development-guides">Development Guides</a></li><li class="footer__item"><a class="footer__link-item" href="/docs/contributing">Contributing</a></li><li class="footer__item"><a class="footer__link-item" href="/docs/showcase">Showcase</a></li><li class="footer__item"><a class="footer__link-item" href="/docs/credits">Credits</a></li></ul></div><div class="col footer__col"><div class="footer__title">Misc</div><ul class="footer__items"><li class="footer__item"><a class="footer__link-item" href="/docs/privacy">Privacy &amp; Security</a></li><li class="footer__item"><a class="footer__link-item" href="/docs/license">License</a></li><li class="footer__item"><a href="https://github.com/Lissy93/dashy/blob/master/.github/LEGAL.md" target="_blank" rel="noopener noreferrer" class="footer__link-item">Legal</a></li><li class="footer__item"><a class="footer__link-item" href="/docs/code-of-conduct">Code of Conduct</a></li><li class="footer__item"><a class="footer__link-item" href="/docs/changelog">Changelog</a></li></ul></div></div><div class="footer__bottom text--center"><div class="footer__copyright"><a href="https://dashy.to">Dashy</a> - The Self-Hosted Dashboard for your Homelab<br>License under <a href="https://github.com/Lissy93/dashy/blob/master/LICENSE">MIT</a>. Copyright © 2021 <a href="https://aliciasykes.com">Alicia Sykes</a></div></div></div></footer></div>
<script src="/assets/js/runtime~main.02cab8fc.js"></script>
<script src="/assets/js/main.dc7bf884.js"></script>
</body>
</html>