Using basic auth for different permissions (folder is protected and browsable, subfolders are not)

1. Caddy version (caddy version): Latest

2. How I run Caddy:

a. System environment:

Ubuntu 20.04

b. Command:

sudo service caddy start

c. Service/unit/compose file:

N/A

d. My complete Caddyfile or JSON config:

# The Caddyfile is an easy way to configure your Caddy web server.
#
# Unless the file starts with a global options block, the first
# uncommented line is always the address of your site.
#
# To use your own domain name (with automatic HTTPS), first make
# sure your domain's A/AAAA DNS records are properly pointed to
# this machine's public IP, then replace ":80" below with your
# domain name.

recording.bpsdassist.org.au {
	# Set this path to your site's directory.
	#root * /usr/share/caddy
	root * /var/www/html

	# Enable the static file server, and browsing of a folder.
	file_server browse

	# New password hashes are made with caddy hash-password.
	basicauth /tasks/* {
		Bob <CREDENTIALS> # Admin, can browse all folders
		Brett <CREDENTIALS> # Normal person, can browse subfolders 
	}
	# Another common task is to set up a reverse proxy:
	# reverse_proxy localhost:8080

	# Or serve a PHP site through php-fpm:
	# php_fastcgi localhost:9000
	#
	handle_errors {
		@404 {
			expression {http.error.status_code} == 404
		}
		rewrite @404 /404.html

		file_server
	}
}

# Refer to the Caddy docs for more information:
# https://caddyserver.com/docs/caddyfile

3. The problem I’m having:

What I would like to try and do, is to have two levels of access.

The file structure is from the root:

  1. /tasks
  2. /tasks/task1/file.txt (there could be many variations of task1 names)

For 1. I can do, using basicauth for /tasks/* , and the entry in the config you can see is file_server browse.

What I’m not sure though, is how I could do 2. I don’t know the foldernames that have been generated in advance, but they would look like:

In other words, an admin can browse the tasks folder with their login.

Otherwise, a normal person that knows to navigate to /tasks/task1 can access that subfolder to browse. I would prefer if that is with it’s own basicauth password, but it’s okay if not.

4. Error messages and/or full log output:

5. What I already tried:

Adding this below the first basicauth entry

basicauth /tasks/*/* { Brett <Hash> }

I can’t do this because of having two basicauth entries. It then overwrites the first entry, and doesn’t work anyway I don’t think.

I’m thinking the file server basics resources may help below, perhaps I could have the admins use /tasks/ which is a redirect, and normal users access it with the base of /task/ externally.

6. Links to relevant resources:

You can use handle blocks for this. With handle, only the first matching handle will run, so if one with a longer path matcher gets matched first, the next will be ignored.

handle /tasks/tastk1/* {
	basicauth {
		Bob <pass>
	}
}

handle /tasks/* {
	basicauth {
		Alice <pass>
	}
}

handle {
	# Optional fallback if none of the above matched
}

That does sound perfect, with the idea of matching and order being able to stack things.

With your

handle /tasks/tastk1/* {
	basicauth {
		Bob <pass>
	}
}

Example, would it be possible to have that catch all subfolders of tasks/ ?
Because it wouldn’t be known what exists at the time

Yes, it’s possible to match on /tasks/*/* which is a “globular match”

The actual rules for the globs is explained here (sourced from the Go stdlib):

https://pkg.go.dev/path/filepath#Match

(Note that it unfortunately doesn’t support ** globs to select multiple path segments, so that’ll depend on what you need).

Sorry, but /tasks// does not seem to match, or at least match a handle path with basic auth.
I tried the following:

      root * /var/www/html

        # Enable the static file server, and browsing of a folder.
        file_server browse

# Access to the subfolders only, does not work. Examples:
# /tasks/test/
# /tasks/test/file.txt

        handle /tasks/*/* {
                basicauth {
                        lowaccess <CREDENTIAL>
                }
        }

        # New password hashes are made with caddy hash-password.
# Fall back to admin auth checking, still works.
        handle /tasks/* {
                basicauth {
                        Brett <CREDENTIAL>
                }
        }

With the above config lowaccess basicauth never works, being prompted again.

Is that problem to do with a multiple path segment like you mentioned? And could I get around it by using a path_regexp mentioned just below your doc reference?

Yeah, you can use path_regexp.

I’ll dig deeper to understand why that matcher didn’t work for you.

I’ve used the following as a temporary solution, but it feels pretty clunky - I have to duplicate the admin users into the higher folder. It also relies on me putting a prefix on each sub folder so I can match them in the handle.

The order that these are in the config file didn’t seem to make a difference, and if I didn’t duplicate the users, the admins wouldn’t be able to view the actual notes - just browse the folders.

# inside a path... { 

# Low level person access, duplicated admin users so they can access here too. (otherwise the admins couldn't access here)

file_server browse

# These people can view individual notes, but can't browse the root folder.
        handle /tasks/note-prefix-* {
                basicauth {
                        lowaccess hashpwd
                        anotherlowaccess hashpwd
                        admin hashpwd
                        anotheradmin hashpwd

                }
        }

# Base admin access, they can browse the base folder.
        handle /tasks/* {
                basicauth {
			admin hashpwd
			anotheradmin hashpwd
                }
        }

You can use Caddyfile snippets to deduplicate lists of credentials you’re putting in multiple places.

You’ve only copied a part of your config, so I don’t know how to comment on any other part of that.

Not much else in the rest of the config, but a snippet for the “admins” would help with the duplication.

config follows:

# The Caddyfile is an easy way to configure your Caddy web server.
#
# Unless the file starts with a global options block, the first
# uncommented line is always the address of your site.
#
# To use your own domain name (with automatic HTTPS), first make
# sure your domain's A/AAAA DNS records are properly pointed to
# this machine's public IP, then replace ":80" below with your
# domain name.

recording.bpsdassist.org.au {
	# Set this path to your site's directory.
	#root * /usr/share/caddy
	root * /var/www/html

	# Enable the static file server, and browsing of a folder.
	file_server browse

	# New password hashes are made with caddy hash-password.
	# These people can view individual notes, but can't browse the root folder.
        handle /tasks/note-prefix-* {
                basicauth {
                        lowaccess <hashpwd>
                        anotherlowaccess <hashpwd>
                        admin <hashpwd>
                        anotheradmin <hashpwd>

                }
        }

# Base admin access, they can browse the base folder.
        handle /tasks/* {
                basicauth {
			admin <hashpwd>
			anotheradmin <hashpwd>
                }
        }

}

# Refer to the Caddy docs for more information:
# https://caddyserver.com/docs/caddyfile

This topic was automatically closed after 30 days. New replies are no longer allowed.