OpenCloud with Authentik-MFA: direct at home, via Tailscale on the go or publicly via Cloudflare – without your own public IP #3586
LHBL2003
started this conversation in
Show and tell
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Use the full LAN speed at home with your family, securely access OpenCloud and your home network via Tailscale-VPN on the go, and share files with friends and acquaintances – without any VPN. No static public IP, additional protection through Authentik with MFA/2FA, and almost no ongoing cloud service costs. All you need is your own domain address.
The vision
Family photos should be accessible on the go – but not with a stolen password alone. This guide adds Authentik and an email code to the OpenCloud login without recreating existing user accounts, files, or Spaces. Further MFA authentication options should then be easy to implement.
At home, access goes directly to the NAS. Family members mainly use Tailscale on the go; on someone else's computer, a browser accessing through Cloudflare Tunnel is enough. This requires neither your own public IP nor a rented server, also called a VPS. If a NAS, internet connection, and email sending are available, ideally only the domain costs should be added.
The aim was to make OpenCloud and Immich shares and Home Assistent accessible from outside via MFA, but in a way that OpenCloud WebDav and the Home Assistant Alexa Skill continue to work without being blocked by MFA. Here we set up the OpenCloud integration. Immich and Home Assistant need their own configuration, but this establishes the foundation.
What works afterwards:
Note: MFA protects account login, not automatically public share links or every API request. Shares require their own permissions, and where appropriate a password and expiration date. The Alexa integration also works with account linking and tokens; an interactive login page placed in front of it can interrupt this connection.
🌐 I hope the translation from German into English is correct :)
✍️ I’ve documented it retrospectively and hope that nothing is missing. If anything is, please feel free to post the relevant section with a correction. Ideally, include ‘before’ and ‘after’ versions. I’ll then be happy to update it accordingly.
Contents
1. Starting point and example values
OpenCloud is already running: users can log in and access their files. Authentik, Nginx Proxy Manager (NPM), and AdGuard Home are also installed and administrable. This guide connects these services; it does not start with Docker or NAS installation.
The setup described uses Docker Compose on a UGREEN NAS 4800 Pro. Komodo manages the stacks. The same Compose files can be used without Komodo.
For the public route, we need an internet domain such as
example.comwith DNS management at Cloudflare. The domain may have been purchased from another provider. A website is not part of this. Authentik also needs SMTP access to send the login codes.Replace these values
example.comhttps://opencloud.example.comhttps://authentik.example.com/192.168.10.20192.168.10.20192.168.10.0/24alexalex@example.comAdGuard and NPM may run on other devices; in that case, enter their respective IP addresses. All paths and domains in this guide are examples.
opencloud.example.comrepresents your own OpenCloud address; anyone usingcloud.meinedomain.de, for example, substitutes it everywhere.Setup versions
The browser, iPhone app, Windows client, and WebDAV were used. The Android entries are included as a supplement but have not been tested in practice.
2. How the connections work
At home
AdGuard supplies the IP address; files then pass through NPM to OpenCloud. Authentik handles login, not file transfers.
9700is the published NAS port for Authentik here, not its internal container port.On the go with Tailscale
Split-DNS provides the internal NAS IP; the subnet route makes it reachable. Simply enabling Tailscale is not enough: if DNS still returns the public address, access may still go through Cloudflare.
Without Tailscale, for example on someone else's computer
cloudflaredestablishes the outbound connection. This route therefore requires neither a public NAS IP nor inbound router port forwarding. An ordinary Cloudflare DNS entry alone does not replace the tunnel. With public access, the browser's TLS connection initially terminates at Cloudflare; LAN and Tailscale lead directly to NPM.What happens during login
The login protocol is called OpenID Connect (OIDC). Authentik issues the tokens and is the Issuer.
preferred_usernameis a user detail transmitted in them, a Claim. The desktop client additionally protects the code exchange with PKCE.The OpenCloud container must also be able to reach Authentik through DNS and HTTPS. A visible login page only proves that the browser can get there. The NAS and clients also need a correctly synchronized clock for token validation.
3. Map existing users
Step 1: Align usernames
Explanation
We link accounts through the username:
alexin Authentik belongs toalexin OpenCloud. The existing OpenCloud account is adjusted for this; no new one is created.All usernames are consistently lowercase. The reason for this is Home Assistant, which uses lowercase usernames. This means we do not need an additional conversion rule. Separate names such as
Alexandalexmust not later map to the same target account through lowercasing. A case-insensitive login lookup does not replace this consistent storage. In Authentik, you can create the usersAlexandalex; these are two different users, which is why capitalization matters.Configuration
alex, and save.Note: First name, last name, and email do not determine this mapping. Authentik may allow login by email; the username is still passed to OpenCloud.
Step 2: Prevent users from changing their own usernames
Explanation
If
alexchanges his name toalex-neuin his Authentik profile, OpenCloud can no longer find the associated account. Users must therefore not be allowed to change their login name themselves.Configuration
In Authentik 2026.8.1, changing one's own username is already disabled by default. Only if this feature was previously enabled: Under Authentik → System → Settings, disable Allow users to change username and save. Authentik default value
Anyone who also wants to lowercase profile details when saving can find the optional policy in the appendix. It is not required for account mapping.
4. Create OpenCloud clients in Authentik
Step 3: Create applications with OIDC providers
Explanation
The web browser, desktop, and iPhone use different client IDs and redirect addresses. Each client therefore receives its own provider. They all use the same issuer and signing key.
Configuration
In Authentik → Applications → Applications, create the following applications, each with an OAuth2/OpenID Connect Provider. If the interface offers the two separately, first create the provider under Applications → Providers and then assign it to the application.
opencloud-webwebopencloud-desktopOpenCloudDesktopopencloud-iosOpenCloudIOSopencloud-androidOpenCloudAndroidFor each new provider, set or add these details. Fields not listed remain at their preset values:
Publicdefault-provider-authorization-implicit-consentauthentik Self-signed Certificateoffline_accessSame identifier is used for all providersAdd the redirect addresses from step 4 to the respective provider and save.
openid,profile, andemailare already selected when creating a new provider; no additional scope is needed for the web provider. Authentik 2026.8.1: Scope presetsNote:
implicit-consentin the "Authorization-Flow" name does not mean that theImplicitgrant needs to be enabled. The signing key is also not the HTTPS certificate from NPM. The web client below requests onlyopenid profile email; native clients additionally needoffline_accessfor renewable sessions.Step 4: Enter redirect addresses
Configuration
In Authentik → Applications → Providers → edit the respective provider → Redirect URIs/Origins, enter the appropriate addresses.
OpenCloud Web: Mode Strict, type Authorization, one line each:
OpenCloud Desktop: Mode Regex, type Authorization, one line each:
This returns the browser to the OpenCloud client on the PC. Its port changes; a fixed NAS address would be wrong here. These two entries replace earlier, broader regex patterns.
OpenCloud iOS: Mode Strict, type Authorization:
OpenCloud Android, optional: Mode Strict, type Authorization:
Note: The app addresses remain unchanged, even with your own domain. Do not enter a blanket permission with
.*. If another client version uses a different callback, specifically add its address.Step 5: Assign applications and providers
Configuration
In Authentik → Applications → Applications, open each OpenCloud application:
If the application was created together with its provider in step 3, the assignment is already complete. Only for applications and providers created separately, select the appropriate provider and save.
Optionally, an icon can be added under UI settings.
Note: Without application bindings, Authentik generally allows all its users access to the application. In this setup, OpenCloud still requires an existing account with a matching username; file and Space permissions continue to apply there. An additional restriction to specific Authentik groups is optional and is not set up here. The MFA stage bindings in chapter 6 are unaffected by this. Authentik: Application access
5. Set up DNS and Nginx Proxy Manager
Step 6: Resolve to the NAS IP on the home network
Explanation
AdGuard should answer both domains with the internal NAS IP. This keeps logins and file transfers at home from going through Cloudflare.
Configuration
In AdGuard Home → Filters → DNS rewrites or Filters → DNS rewrites, create these rules:
opencloud.example.com192.168.10.20authentik.example.com192.168.10.20Then query your own domains in Windows PowerShell:
The NAS IP must appear under IPAddress. This checks the desired name resolution, but does not by itself prove which DNS server answered.
Note: AdGuard should be set as the DNS server in the router's DHCP distribution. And a public provider for „Secure DNS“ in Chrome or differing IPv6 answers can bypass the local route.
Step 7: Set up the domain and HTTPS certificate
1. Buy a domain from Cloudflare
Explanation
For this setup, we buy a new domain directly from Cloudflare. It serves as the common base for addresses such as
opencloud.example.comandauthentik.example.com. The subdomains are set up later and do not need to be purchased individually.Choose an available name with an inexpensive extension, for example
meine-domain.uk, provided that name is still available. It does not have to be your country's extension: for the functions described here,.de, for example, offers no technical advantage over.ukor.com. Prices and registration conditions differ depending on the extension. Therefore, compare not only the purchase price but also the annual renewal costs..ukis an example, not a guarantee of the lowest price at any given time.Configuration
https://and withoutopencloud.in front of it. Compare available names and extensions.Cloudflare also sets up DNS management for the domain purchased there; no manual nameserver change is needed. The domain costs the displayed registration or renewal fee. A paid website plan is not necessary for this setup. Cloudflare: Buy a domain
Note: An existing domain can also be connected to Cloudflare without necessarily transferring it to Cloudflare as the domain provider. This alternative route is not described here. If the domain is already active at Cloudflare, the purchase can be skipped. Cloudflare: Add an existing domain In the following examples,
example.comis a placeholder for your own domain.2. Create an HTTPS certificate in NPM
Explanation
The NAS does not use its own publicly reachable IP or an inbound internet port 80, so a DNS-Challenge is needed. This still allows Let's Encrypt to confirm the domain through a DNS entry. This DNS-Challenge therefore works without public access to the NAS.
Configuration
If a suitable certificate does not yet exist:
example.comand*.example.com(type and click "Create example.com" below to apply).This can also secure
immich.example.comandha.example.com.*.example.comdoes not cover deeper names such asapp.intern.example.com.Note: Further details are available from NPM and the Cloudflare DNS plugin. The token stays private. A Cloudflare Origin certificate alone is not sufficient for trusted HTTPS during direct LAN access such as
MyNas.local.Step 8: Create the two proxy hosts
Explanation
The client reaches NPM through
NAS-IP:443. NPM then communicates through the NAS IP with the published port of OpenCloud or Authentik – not with127.0.0.1inside its own container.Configuration
opencloud.example.comauthentik.example.comhttphttp192.168.10.20192.168.10.2092009700Note on the switches:
redirect_uri=http://127.0.0.1:PORT. This results in 403 Forbidden – openresty, before Authentik even processes the login. Therefore, turn it off there; redirect validation in Authentik remains in place.The OpenCloud port
9200is made available in chapter 7 through its Compose file list. Until then, the new OpenCloud proxy host may not yet be reachable.Step 9: Provide a shared discovery address
Explanation
OpenCloud and the apps need the login information at
https://authentik.example.com/.well-known/openid-configuration. NPM forwards exactly this address to the web provider already created.Configuration
opencloud-webis the Application-Slug from chapter 4.Do not add an additional
serverblock or a secondlocation /. The change belongs in NPM, not in its automatically generated files.Check
Open
https://authentik.example.com/.well-known/openid-configurationin the browser. The response must contain JSON, withissuerexactlyhttps://authentik.example.com/and publicly usable HTTPS endpoints. If you get a login page, 404, or an internal container address, check the proxy rule, Application-Slug, and issuer setting. All providers must use the same signing key because the shared discovery points to the web provider. Authentik/OpenCloud integration6. Set up email code and login flow
Step 10: Prepare email sending and the email stage
Explanation
OpenCloud's mail configuration does not apply to Authentik. Authentik needs its own SMTP settings and a stage that sets up the email authenticator.
Configuration
Enter the credentials in the Authentik stack's
.env:These short variable names only work if the Compose file passes them to Authentik under
environmentfor server and worker:Do not enable both encryption options (TLS/SSL). Then redeploy the Authentik stack. SMTP settings
Then, in Authentik → Flows and Stages → Stages:
mfa-email-setup.E-Mail-Code; this is only the displayed name of the factor.Note: Do not select the general Email Stage for verification or recovery. For the second factor, we need the Email Authenticator Setup Stage. The user must have a reachable mailbox recorded.
Step 11: Combine the password prompt and make MFA mandatory
Explanation
Username and password should be requested on the same login page. Authentik then requires a second factor. Without a configured factor, the MFA check must not be skipped as it is by default; instead, email setup is started.
Configuration
In Authentik → Flows and Stages → Flows, click the blue name default-authentication-flow in the Identifier column – not the pencil icon. Open the Stage Bindings tab.
Skipto Force the user to configure an authenticatorThe sequence then looks like this:
Note: Users with an allowed second factor already configured can continue to use it. Selecting
mfa-email-setupdetermines setup for users without a suitable factor; it does not enforce email exclusively for all users.Step 12: Check the login
The default brand already uses
default-authentication-flow; reassignment is not necessary. Other applications using this flow also receive the MFA rules. Authentik 2026.8.1: Default brandOnly if the flow assignment was previously changed: In Authentik → Applications → Providers → OpenCloud provider → Advanced flow settings → Authentication Flow, select the
default-authentication-flowedited here. This is not an additional step for an unchanged default installation.Check
Open Authentik in a new private browser window and log in with a regular user. The email must arrive; an incorrect code must not complete the login.
Note: Existing Authentik sessions can avoid another password/MFA prompt.
seconds=0on the Validation stage does not invalidate an existing SSO session. Password and MFA recovery are separate processes and are not automatically protected by this login flow.7. Activate Authentik in the OpenCloud stack
Step 13: Explain and place the files
Explanation
Two files are needed for the integration:
authentik-idp.ymlconfigures the OpenCloud container, andcsp.yamladds browser permissions. Both belong to the OpenCloud setup, not in the Authentik stack. In this step, you place them; they are activated in step 15.authentik-idp.yml – Login and account mapping
The additional Compose file switches login to Authentik. It maps Authentik users to existing OpenCloud accounts through the username and prevents new accounts from being created automatically. It also mounts the CSP file read-only in the container.
These settings are already included in the template:
PROXY_USER_OIDC_CLAIM: preferred_usernamePROXY_USER_CS3_CLAIM: usernamePROXY_AUTOPROVISION_ACCOUNTS: falsePROXY_ROLE_ASSIGNMENT_DRIVER: defaultGRAPH_ASSIGN_DEFAULT_USER_ROLE: trueOC_EXCLUDE_RUN_SERVICES: idpAn Authentik account alone is not enough:
alexmust also exist in OpenCloud. Roles and Space permissions remain in OpenCloud. This reuses existing accounts instead of creating separate accounts for Authentik. The way back to the previous login is described in section 13. OpenCloud: External IdPConfiguration
customfolder in the existing OpenCloud stack directory.authentik-idp.ymlthere, paste the contents of the following collapsible box, and save.🔵 authentik-idp.yml – show full file contents (open collapsible box here)
Note – only for custom changes:
OC_EXCLUDE_RUN_SERVICESdetermines which OpenCloud services do not start. Ourauthentik-idp.ymlentersidpthere, disabling the previous login service. If you have already disabled other services through this parameter, their names must remain in this line, withidpadded. Otherwise, they could start again. Without such custom entries, nothing needs to be changed.csp.yaml – Browser permissions
The
csp.yamlspecifies which additional sources the browser may load for OpenCloud. It supplements the rules OpenCloud already includes. The template therefore contains only the additions for this setup; for example, diagrams.net is already allowed by default.For Euro Office, permission under
frame-srcis required. The document editor is displayed within the OpenCloud website but comes from a different address. The Compose file tells OpenCloud this address; only the CSP allows the browser to embed the editor.Without this entry, both creating Office documents and Open with Euro Office for existing DOCX files failed when reproducing the setup. The editor is blocked in the browser; this does not indicate whether a file has already been created on the server side. Therefore, keep the Euro Office entry. Explanation of
frame-srcThe other entries allow:
connect-src: Requests from the OpenCloud web interface to Authentik for login.frame-srcfor Authentik: Embedded login windows, if the web client uses them. A normal redirect does not need this permission.media-src: Audio and video throughblob:addresses generated in the browser.worker-src: Background scripts from OpenCloud itself ('self') and throughblob:addresses. These scripts may be needed depending on the web application.The template uses
PROXY_CSP_CONFIG_FILE_LOCATIONto supplement the defaults of OpenCloud 7.5.0. Do not switch toPROXY_CSP_CONFIG_FILE_OVERRIDE_LOCATION: that would replace the defaults, for which this short file alone is not sufficient.Configuration
OC_CONFIG_DIRpoints to, for example/volume1/docker-ssd/komodo/docker/opencloud/config.csp.yamlthere, paste the contents of the following collapsible box, and save. The placeholders remain unchanged; their values come from the stack environment in step 14.🔵 csp.yaml – show full file contents (open collapsible box here)
Note on placement: The
csp.yamlis stored permanently in the configuration folder on the NAS – not undercustomand not directly in the container. Theauthentik-idp.ymlmakes it available read-only to OpenCloud at/etc/opencloud/csp.yaml. This preserves it when the container is recreated. User files do not belong in this configuration folder. The file extensions differ:authentik-idp.ymlandcsp.yaml.Step 14: Add to the OpenCloud environment
Explanation
The files from step 13 use variables for the addresses. You therefore enter the Authentik address in the OpenCloud stack environment instead of replacing it in the YAML files.
Configuration
.envor Komodo → Stacks → opencloud → Config → Environment.IDP_DOMAINcontains only the hostname;IDP_ISSUER_URLincludeshttps://and the trailing slash.OC_DOMAIN,OC_CONFIG_DIR, andOC_DATA_DIR. IfOC_CONFIG_DIRis currently missing, enter the existing configuration folder from step 13.Note: The
authentik-idp.ymlpassesIDP_DOMAINto OpenCloud. For Euro Office, the existingweboffice/euro-office.ymlalready handlesEURO_OFFICE_DOMAIN. OpenCloud inserts these addresses when reading the CSP. The*.opencloud.testaddresses there are only fallback values for missing variables, not additional domains to set up.Client IDs and scopes are specified in the
authentik-idp.ymland do not also need to go in the.env. Only adjust already existing, differingOC_OIDC_CLIENT_*orWEBFINGER_*values to the IDs from step 3, or remove the relevant overrides.Step 15: Add to the Compose file list
Explanation
Placing the
authentik-idp.ymlalone does not activate it yet. The OpenCloud stack must use it in addition to its existing Compose files. It goes at the end of the file list so that its login settings override the previous defaults.Configuration
external-proxy/opencloud-exposed.ymlif this entry is still missing. Replace an existingexternal-proxy/opencloud.ymlwith it; do not include both.custom/authentik-idp.ymlas the last file. Do not activate a conflicting Keycloak/IdP overlay at the same time.With the existing Office and search services, the list in this setup looks like this:
Keep existing Office and search services. They do not need to be set up again for the MFA integration.
Note on NPM access:
external-proxy/opencloud-exposed.ymlsetsPROXY_HTTP_ADDR: "0.0.0.0:9200"and publishes0.0.0.0:9200:9200. This allows NPM to reach OpenCloud throughNAS-IP:9200. The alternativeexternal-proxy/opencloud.ymlbinds only to loopback and does not suit this access route. Allow backend ports only for the necessary internal access, not through the router to the internet.Note on the file list:
csp.yamlhere. It is already included throughauthentik-idp.yml.Step 16: Redeploy OpenCloud and log in
Configuration
Redeploy in the stack manager. A simple
restartdoes not apply new environment values and mounts.When managing Compose manually on the NAS, first check with your own complete file list; for the list above, the command is:
cd /volume1/docker-ssd/komodo/stacks/opencloud docker compose \ -f docker-compose.yml \ -f weboffice/euro-office.yml \ -f external-proxy/euro-office-exposed.yml \ -f search/tika.yml \ -f search/opensearch.yml \ -f external-proxy/opencloud-exposed.yml \ -f custom/authentik-idp.yml \ config --quietThen, with the same list, replace
config --quietwithup -d. Keep the previous Compose project name so that the existing containers and volumes remain associated. Do not remove data volumes. The filenames come from opencloud-compose and must match your own version.Check
On the home network, open a new private browser window:
https://opencloud.example.com.The OpenCloud integration is now set up. If login fails, first use chapter 11 before changing further settings.
Note on
INSECURE: WithINSECURE=true, services that use this value can also accept invalid HTTPS certificates. Therefore, do not set the value totruejust to bypass a login error. If it is alreadytrue, do not change it without checking: depending on the existing configuration, Euro Office, for example, might no longer work afterwards.8. Connection tests for apps and WebDAV
iPhone and Windows
https://opencloud.example.com.The server address remains the same on the go. Do not enter the Authentik address or NAS IP as the OpenCloud server.
Note: In this guide, accounts are mapped through the username. This keeps the mapping the same even if the email address changes. Apps on Windows, Mac, or iPhone may still have the previous mapping stored. If login fails because of this, remove the account only from the affected app and then add it again. This is not necessary if login works. Back up unsynchronized files and offline data beforehand. Do not delete the OpenCloud user, Spaces, or local folders.
Alternatively, mapping through the email address can be configured in the
authentik-idp.yml:PROXY_USER_OIDC_CLAIM: "email"andPROXY_USER_CS3_CLAIM: "mail".PROXY_AUTOPROVISION_ACCOUNTS: "false"remains in place. Authentik must transmit the email address in the token; it must match the email field of the existing OpenCloud account and be unique. Changes to these addresses must be controlled so that no one can use another account's address for mapping. This is independent of whether a username or email is entered in the Authentik login window. For the setup described here, mapping through the username remains configured.WebDAV: Scanners and other clients
This section is only relevant if you use WebDAV – for example, with a WebDAV-capable scanner that stores documents directly in OpenCloud, or a client for file access. Otherwise, you can skip it.
Set up the connection
In OpenCloud → personal settings → App Tokens, generate a separate token for the scanner or client. Enter the following in its WebDAV settings:
alex, not their email addressA Space address looks like this, for example:
Use the actual IDs; do not derive them from the Space name. Do not include credentials in published configurations.
Test the connection
Use the scanner to save a test scan in the target folder, or upload a small file with the WebDAV client. Then check in OpenCloud whether the file has arrived in the intended folder. For read-only access, download an existing file instead.
Note: App tokens allow access without an interactive MFA dialog. They must be kept secret and are revoked in OpenCloud; blocking an account in Authentik alone does not guarantee that existing app tokens are blocked. Do not indiscriminately enable
PROXY_ENABLE_BASIC_AUTH=truefor this. OpenCloud app tokensIf a scanner should only access
Scans, use an account with the appropriate permissions in OpenCloud. A separate token alone does not restrict access to this folder.9. Access through Tailscale on the go
Step 17: Set up the NAS, subnet route, and DNS
Explanation
Through Tailscale, your phone or notebook reaches OpenCloud through the internal NAS address – without the detour through Cloudflare. This requires two things: a route into the home network (subnet route) and internal resolution of your domain through AdGuard (Split-DNS).
For private use, the free Personal plan offers up to 6 users, unlimited personal devices, and 50 tagged devices („Tagged Resources“), for example servers, NAS devices, or subnet routers. A NAS does not count as a Tagged Resource simply because of its function, but only once the corresponding tag is assigned. As of: September 2026. Tailscale plans
That is enough, for example, for two parents and four children, each with their own account. Each person can connect several of their own devices, such as a phone, tablet, and notebook. Separate accounts make it possible to assign access rights per person and revoke them individually if needed. You can also accommodate more than 6 family members if, for example, two share an account (mother and father, siblings, and the maternal and paternal grandparents.) This also allows larger families to be brought together through the Tailscale tunnel.
The examples use the home network
192.168.10.0/24, the NAS with AdGuard at192.168.10.20, and the domainexample.com. Replace these three values with your own.1. Tailscale container on the NAS
Configuration
Place the Compose configuration in the Tailscale stack on the NAS, not in the OpenCloud stack. For an existing container, keep its data path.
🔵 Tailscale – Compose example for the NAS setup (open collapsible box here)
TS_AUTHKEY. Do not write it in the published Compose file.TS_ROUTESto your own home network. This means the network, for example192.168.10.0/24, not the individual NAS IP.The mounted data folder stores the device login; a normal restart does not require a new Auth Key. If the device is deleted in Tailscale and logged in again, use a new single-use key. Tailscale Docker parameters
Note:
privileged: truecorresponds to this NAS setup and gives the container extensive host permissions; it is not a general minimum requirement for Tailscale. No Exit Node is set up here: only the route into the home network should go through the NAS, not all internet traffic.2. Approve the subnet in Tailscale
To operate as a subnet router, IP forwarding must also be enabled on the NAS. If Tailscale reports missing forwarding, set it up on the NAS according to the subnet router guide.
TS_ROUTESadvertises the network but does not by itself enable host forwarding.Configuration
192.168.10.0/24and save.Note: A newly set up Tailscale network initially allows communication between all devices in your own Tailscale network. As long as this default rule remains unchanged, no additional Tailscale access rules are needed for this. The subnet route must still be approved as described above.
With restricted access rules, authorized users must be allowed to reach NPM at
192.168.10.20:443(TCP) and AdGuard at192.168.10.20:53(UDP and TCP). An active NAS firewall must also allow these connections. No additional firewall settings were needed for this in the UGREEN setup described here.3. Resolve your own domain through AdGuard
Configuration
In Tailscale administration → Network → DNS → Nameservers, add a custom nameserver:
192.168.10.20– NAS address of AdGuardexample.comSave. Then click Enable under Network → DNS → MagicDNS if MagicDNS is not yet enabled.
Requests for
opencloud.example.comandauthentik.example.comthen go to AdGuard. Its DNS rewrites already configured return the internal NAS IP. This Split-DNS rule does not apply to other domains. MagicDNS alone does not replace this rule: It provides names for devices on the Tailscale network. Tailscale DNS · MagicDNSDNS requests for other internet domains continue to use the DNS servers otherwise configured on the device, for example those of the mobile provider. This Split-DNS rule does not forward them to AdGuard on the home network. Anyone who also wants AdGuard to resolve these requests while Tailscale is connected can adjust the global DNS settings in Tailscale for this. This redirects only DNS requests, not automatically all internet traffic.
Note: No Exit Node is used in this setup: only access to the home network goes through Tailscale, while other internet traffic continues to use the device's normal connection. The DNS option
Use with exit nodetherefore remains disabled. It does not activate an Exit Node, but merely determines whether AdGuard should also be used as the DNS server with an Exit Node selected later.4. Test access on the go
Configuration and check
tailscale set --accept-routes=trueif necessary.https://opencloud.example.com, log in through Authentik, and transfer a file.On the Windows notebook, you can additionally check in PowerShell whether the internal address is returned:
192.168.10.20is expected here. The familiar domain names remain in the browser; NPM continues to supply the HTTPS certificate. No additional Tailscale certificate is needed for this route.Note: If the home network and another Wi-Fi network have the same subnet, routing conflicts can occur. Mobile data is therefore suitable for an unambiguous first test.
10. Set up public access through Cloudflare
Step 18: Forward the tunnel to NPM
Explanation
This route is intended for devices without Tailscale. The tunnel also goes through NPM so that the discovery rule from step 9 applies. The domain was already set up at Cloudflare in step 7. Public access to the prepared services is now enabled.
Configuration
1. Create a tunnel
There are numerous easy-to-understand video guides showing how to set up a Cloudflare tunnel with Docker on a NAS or Linux system.
nas-tunnel, and confirm with Create Tunnel. The name is only for recognition and does not have to match a domain.cloudflaredconnector. Use the tunnel token displayed there for the NAS container.The connector establishes the connection from the NAS to Cloudflare. No inbound router port forwarding is needed for this. Treat the token like a password and do not publish it.
2. Publish OpenCloud and Authentik
In Cloudflare → Networking → Tunnels → nas-tunnel → the
Routestab at the top → Add route → Published application, create one entry each for OpenCloud and Authentik. Enter the subdomain (opencloudorauthentik) and select your own domain. Leave the path field empty:opencloud.example.comauthentik.example.comhttps://192.168.10.20:443https://192.168.10.20:443opencloud.example.comauthentik.example.comopencloud.example.comauthentik.example.comEnter Host-Header and Origin Server Name without
https://or a path. They ensure that the correct NPM host and its certificate are used despite the internal target IP.Check
Outside the home network, turn off Tailscale. Open OpenCloud in a new private browser window, log in, and upload and download a small file. This actually tests the public route.
Note: Do not publish NAS, NPM, or database administration through this tunnel. TLS verification to NPM remains enabled for the two application addresses.
Understanding the upload limit correctly
Cloudflare Free limits an upload request to 100 MB. This is not an equivalent download limit and, with clients using suitable chunking, is not necessarily the maximum file size either.
A single 150 MB upload can fail with HTTP 413; this also happens with large videos in Immich. This Cloudflare limit does not apply over LAN or Tailscale; a higher NPM setting alone does not remove it on the public route. Cloudflare: HTTP 413
11. Narrow down errors systematically
„Not logged in“ appears after MFA
In the case described, the administrator worked, but the regular user did not. Their OpenCloud login name was still the email address; Authentik was already supplying the username.
In OpenCloud → Administration → People, compare the login name with Authentik → Directory → Users → Username and align it on the existing account. Also, for
401on/graph/v1.0/meafter the token exchange, check user mapping and roles first. The error alone does not prove a browser or proxy defect.The desktop shows „403 Forbidden – openresty“
In NPM → edit Authentik proxy host, first check Block Common Exploits. The local desktop callback can trigger this protection rule.
If the error remains, compare NPM and Authentik logs for the same request.
openrestyalone does not prove the cause. Do not set blanket redirect permissions, and do not disable PKCE.WebDAV reports „PermissionDenied“ or „Authentication error“
In the OCR case, the token was correct, but the email address was entered as the user in the client. Access worked with the OpenCloud username. Then, if necessary, check the token, actual Space URL, and write permissions.
An app still expects the old email identity
Disconnect the client account and reconnect it, as described in chapter 8. Keep the existing user in OpenCloud.
„Remote host signaled shutdown“ or „excessive load detected“
Transfer the affected file again and look at the OpenCloud and NPM logs for the same time: was the container restarted, the connection closed, or a limit reached? HTTP/2 is a possible lead to investigate, but not a proven cause in this setup.
File changes are not applied
In Komodo, Info → Show once contained different content from the file edited through SMB. Therefore, correct the source actually used there and redeploy the stack.
For Failed to write contents, check the path, read-only mounts, and NAS ACLs.
rootin the container does not guarantee write permissions to every mounted file; indiscriminatechmod 777is not a solution.View the active OpenCloud configuration
In the NAS terminal, first determine the actual container name:
docker ps --format 'table {{.Names}}\t{{.Image}}\t{{.Ports}}'In the following commands, replace
OPENCloud_CONTAINERwith this name:The expected values, in order, are
https://authentik.example.com/,preferred_username,username,false, andauthentik.example.com. The mount list must show the NAS fileconfig/csp.yamlmapped to/etc/opencloud/csp.yaml.Read the appropriate logs
On the NAS, substitute the actual container names:
For NPM, also read the logs of the affected proxy host. In the NPM data directory, they are usually named
logs/proxy-host-<id>_access.logandlogs/proxy-host-<id>_error.log. Container startup messages are not enough for a failed HTTP request.If
alexworks on the LAN but not over mobile data without Tailscale, investigate the Cloudflare/proxy route. If only the administrator works on the same device, check user mapping first.Note: The Authentik data folder does not have to contain a Compose file; look up its location in the stack manager. Before sharing logs or environment output, remove passwords, tokens, cookies, and private details.
12. Return to the previous login
The integration is deliberately set up as an additional Compose file. To go back, we change the login, not user management or data storage.
Configuration
custom/authentik-idp.ymlfrom the active list. When managing Compose manually, omit the corresponding-fargument. The file does not have to be deleted.idpmust no longer be excluded throughOC_EXCLUDE_RUN_SERVICES.Note: Authentik passwords are not transferred to OpenCloud. If all Authentik changes are in the overlay and the base provides the internal IdP, omitting it and redeploying is sufficient. Existing user management and data volumes remain in place.
Appendix A: Automatically lowercase profile details
Explanation
This optional rule converts, for example,
Alex@Example.comtoalex@example.comwhen saving your own details in the Authentik web interface. It also processes submitted usernames; changing them yourself remains blocked by step 2.Configuration
Note: The policy only applies to changes to your own profile through this User-Settings-Flow. It does not retrospectively rewrite existing accounts and does not apply when creating or editing users under Authentik → Directory → Users. Create new usernames there in lowercase from the start. Changes in OpenCloud are not processed by this policy either.
Assign existing password rules
Anyone using custom password rules binds them in Authentik → Flows and Stages → Stages → relevant password Prompt stage → Validation Policies. A rule created under Customization → Policies alone does not take effect yet. This concerns profile or password changes, not the MFA check configured above. Prompt Stage
Appendix B: Set up TOTP with KeePassXC as an additional MFA method
Explanation
In addition to the email code, you can use a TOTP code from KeePassXC. After your username and password, either email or TOTP is then sufficient. KeePassXC generates the codes on your device, even without an internet connection or working email delivery. Authentik itself must still be reachable for login.
To do this, we allow TOTP in the existing MFA check and then connect your Authentik account to KeePassXC. Nothing changes in OpenCloud, the Compose files, or account mapping.
1. Allow TOTP in the existing MFA check
Configuration – Authentik administration
Not configured action remains set to Force the user to configure an authenticator, as in step 11. Configuration stages also remains set to mfa-email-setup: this selection only concerns initial setup when a user does not yet have a suitable factor. We will set up the additional TOTP device through the personal settings in the next section.
Note: Do not add a second Validation stage to the login flow. Both methods should be available for selection in the same stage, not required one after the other. Authentik: MFA validation and allowed methods
2. Use the existing TOTP setup
Explanation
Authentik 2026.8.1 already includes the flow and stage default-authenticator-totp-setup. They allow personal registration of a TOTP device; you do not need to create them again or add them to the login flow. Authentik: Default TOTP setup
Configuration – personal Authentik account
https://authentik.example.com, log in as the user for whom you want to set up TOTP. Initially, use the email code as before.This setup only applies to the currently logged-in user. For your separate administrator account, repeat it using that account's own login and a separate KeePassXC entry. The menu labels correspond to Authentik 2026.8.1.
Note: If TOTP Device is missing under Enroll, check Authentik → Flows and Stages → Stages → default-authenticator-totp-setup → Edit: Configuration flow must point to the existing flow default-authenticator-totp-setup. In the unchanged default setup, this assignment is already in place.
3. Store the key in KeePassXC
Configuration – KeePassXC and Authentik
Note: If you use Google Authenticator or Microsoft Authenticator, scan the QR code with the app. Then enter the six-digit code displayed there in Authentik and confirm with Continue. You can then skip the KeePassXC setup.
Authentik – alex.4. Try both login methods
Check
https://opencloud.example.comand enter your username and password in Authentik.Authentik may automatically preselect the last-used method next time. The other remains available. Authentik: Selecting the MFA method
Note: If a TOTP code is rejected, first check the time on the KeePassXC device and the NAS and use a freshly generated code. The KeePassXC database must also be available without an OpenCloud login, for example as a local copy. If the password and TOTP key are in the same database, access to that database affects both factors; a separate database with different protection keeps them separate. KeePassXC: Security of TOTP keys
All reactions