Merge pull request #86 from outis1one/claude/gifted-bohr-dfzdig

docs: update Authelia setup instructions to use MERGE workflow
This commit is contained in:
Outis
2026-06-15 20:32:36 -04:00
committed by GitHub
2 changed files with 96 additions and 29 deletions
+35 -11
View File
@@ -156,25 +156,49 @@ kiosk:
- kiosk
```
**Step 3 — Configure session duration and access control** in `~/docker/authelia/config/configuration.yml`:
**Step 3 — MERGE into `~/docker/authelia/config/configuration.yml`** (do not replace your existing config):
**access_control** — Find your **existing** `access_control:` block and add the kiosk rule as the **first** rule inside it.
> **Do NOT create a second `access_control:` block.** YAML silently ignores duplicate keys — Authelia will never see the kiosk rule and the kiosk will get a white screen.
Authelia reads rules top-down — first match wins. The kiosk rule **must** sit above any `two_factor` wildcard rule, otherwise the wildcard matches first.
**Why `one_factor`?** The kiosk authenticates via the API (`/api/firstfactor` — password only). TOTP and WebAuthn require an interactive second step that is impossible from a script, so the kiosk group must use `one_factor`.
*Before (your existing config):*
```yaml
session:
expiration: 1y # absolute session lifetime
inactivity: 90d # idle timeout before logout
remember_me: 1y # duration granted by keepMeLoggedIn
access_control:
default_policy: deny
rules:
# Allow kiosk group to reach any subdomain with one-factor auth
- domain: '*.yourdomain.com'
policy: two_factor
```
*After (add kiosk rule above the two_factor rule — same block, not a new one):*
```yaml
access_control:
default_policy: deny
rules:
- domain: '*.yourdomain.com' # kiosk first — one_factor only
subject: 'group:kiosk'
policy: one_factor
# Optional: bypass Authelia entirely for the kiosk's static IP
# - domain: '*.yourdomain.com'
# networks: ['192.168.1.50/32']
# policy: bypass
- domain: '*.yourdomain.com' # existing rule stays below
policy: two_factor
```
**session** — Keep your existing session block as-is; no changes needed. The kiosk re-authenticates via API on every startup so session expiry barely matters for it.
If you do **not** yet have a session block, add:
```yaml
session:
expiration: 8h
inactivity: 1h
remember_me: 7d
cookies:
- domain: yourdomain.com
authelia_url: https://auth.yourdomain.com
```
**Step 4 — Restart Authelia:**
+61 -18
View File
@@ -5309,11 +5309,14 @@ async function autheliaAuthenticate(){
const decipher=crypto.createDecipheriv('aes-256-cbc',key,iv);
const password=Buffer.concat([decipher.update(enc),decipher.final()]).toString('utf8');
const ctrl=new AbortController();
const timer=setTimeout(()=>ctrl.abort(),10000);
const res=await session.defaultSession.fetch(`${autheliaURL}/api/firstfactor`,{
method:'POST',
headers:{'Content-Type':'application/json','User-Agent':'kiosk/1.0'},
body:JSON.stringify({username:autheliaUsername,password,keepMeLoggedIn:true,requestMethod:'GET',targetURL:''})
});
body:JSON.stringify({username:autheliaUsername,password,keepMeLoggedIn:true,requestMethod:'GET',targetURL:''}),
signal:ctrl.signal
}).finally(()=>clearTimeout(timer));
const body=await res.json().catch(()=>({}));
if(res.ok&&body.status==='OK'){
console.log('[AUTHELIA] Authenticated as',autheliaUsername);
@@ -7169,8 +7172,8 @@ window.addEventListener('DOMContentLoaded',()=>{
touchStartTime=Date.now();
fingerCount=e.touches.length;
}
},{passive:true});
},{passive:true,capture:true});
document.addEventListener('touchend',e=>{
if(e.changedTouches.length>=1){
const touchEndX=e.changedTouches[0].clientX;
@@ -7178,9 +7181,9 @@ window.addEventListener('DOMContentLoaded',()=>{
const deltaX=touchEndX-touchStartX;
const deltaY=touchEndY-touchStartY;
const deltaTime=Date.now()-touchStartTime;
if(deltaTime>SWIPE_MAX_TIME)return;
const absX=Math.abs(deltaX);
const absY=Math.abs(deltaY);
@@ -7191,6 +7194,7 @@ window.addEventListener('DOMContentLoaded',()=>{
}
// 2-finger HORIZONTAL = change tabs
else if(fingerCount===2&&absX>SWIPE_THRESHOLD&&absY<SWIPE_TOLERANCE){
console.log('[TOUCH] 2-finger HORIZONTAL - change tab');
ipcRenderer.send(deltaX>0?'swipe-right':'swipe-left');
}
// 1-finger HORIZONTAL = arrow keys
@@ -7204,7 +7208,7 @@ window.addEventListener('DOMContentLoaded',()=>{
});
}
}
},{passive:true});
},{passive:true,capture:true});
// Show pause button on user interaction (for rotation sites only)
let lastUserInteraction=0;
@@ -9185,8 +9189,8 @@ window.addEventListener('DOMContentLoaded',()=>{
touchStartTime=Date.now();
fingerCount=e.touches.length;
}
},{passive:true});
},{passive:true,capture:true});
document.addEventListener('touchend',e=>{
if(e.changedTouches.length>=1){
const touchEndX=e.changedTouches[0].clientX;
@@ -9194,9 +9198,9 @@ window.addEventListener('DOMContentLoaded',()=>{
const deltaX=touchEndX-touchStartX;
const deltaY=touchEndY-touchStartY;
const deltaTime=Date.now()-touchStartTime;
if(deltaTime>SWIPE_MAX_TIME)return;
const absX=Math.abs(deltaX);
const absY=Math.abs(deltaY);
@@ -9228,7 +9232,7 @@ window.addEventListener('DOMContentLoaded',()=>{
});
}
}
},{passive:true});
},{passive:true,capture:true});
// Optional: Auto-show on text field focus (can be disabled)
let autoShowEnabled = true; // Set to false to disable auto-show
@@ -10039,7 +10043,8 @@ process.stdout.write(Buffer.concat([iv,enc]).toString('base64'));
echo
echo " Copy the \$argon2id\$... output — that is your hash."
echo
echo "2. Add a kiosk user to ~/docker/authelia/config/users.yml:"
echo "2. ADD a kiosk user to ~/docker/authelia/config/users.yml"
echo " (append — do not replace existing users):"
echo
echo " kiosk:"
echo " displayname: \"Kiosk Display\""
@@ -10048,19 +10053,57 @@ process.stdout.write(Buffer.concat([iv,enc]).toString('base64'));
echo " groups:"
echo " - kiosk"
echo
echo "3. Add to ~/docker/authelia/config/configuration.yml:"
echo "3. MERGE into ~/docker/authelia/config/configuration.yml:"
echo
echo " session:"
echo " expiration: 1y"
echo " inactivity: 90d"
echo " remember_me: 1y"
echo " ── access_control ─────────────────────────────────────"
echo " Find your EXISTING access_control block and add the"
echo " kiosk rule as the FIRST rule inside it."
echo
echo " !! DO NOT create a second access_control: block !!"
echo " YAML silently ignores duplicate keys — the kiosk rule"
echo " will be invisible to Authelia and you will get a white"
echo " screen on the kiosk."
echo
echo " Authelia reads rules top-down, first match wins."
echo " The kiosk rule MUST be above any two_factor rule or"
echo " the two_factor wildcard will match first."
echo
echo " ── EXAMPLE — before (your existing config): ──────────"
echo " access_control:"
echo " default_policy: deny"
echo " rules:"
echo " - domain: '*.yourdomain.com'"
echo " policy: two_factor"
echo
echo " ── EXAMPLE — after (add kiosk rule above two_factor): ─"
echo " access_control:"
echo " default_policy: deny"
echo " rules:"
echo " - domain: '*.yourdomain.com' # <-- kiosk first"
echo " subject: 'group:kiosk'"
echo " policy: one_factor"
echo " - domain: '*.yourdomain.com' # <-- existing"
echo " policy: two_factor"
echo
echo " Why one_factor? The kiosk authenticates via the API"
echo " (/api/firstfactor — password only). TOTP and WebAuthn"
echo " require a second interactive step that is impossible"
echo " from a script, so the kiosk group must use one_factor."
echo
echo " ── session ─────────────────────────────────────────────"
echo " Keep your existing session block — no changes needed."
echo " The kiosk re-authenticates via API on every startup so"
echo " session expiry barely matters for it."
echo
echo " If you do NOT yet have a session block, add:"
echo
echo " session:"
echo " expiration: 8h"
echo " inactivity: 1h"
echo " remember_me: 7d"
echo " cookies:"
echo " - domain: yourdomain.com"
echo " authelia_url: https://auth.yourdomain.com"
echo
echo "4. Restart Authelia on your Docker host:"
echo " docker compose restart authelia"