Skip to main content

Protect your first app

You will run a login portal at http://localhost:9080/auth/ and protect /app with a role check. Caddy serves a short message as the example application, so you can learn the access flow without setting up another server.

Complete Install and verify first. This example is tested with caddy-security v1.3.0 and go-authcrunch v1.3.8.

Local learning example

This configuration uses HTTP and two public demo passwords. It binds to 127.0.0.1 and is intended for a disposable local directory. Read Next steps before adapting it for a deployment.

1. Create the configuration​

In your authcrunch-demo directory, create a file named Caddyfile with the following contents. The same file is available in the examples directory.

Caddyfile
# Local learning example: run from a new directory, never on a public host.
{
admin off
persist_config off
storage file_system ./data/caddy

security {
local identity store localdb {
realm local
path ./data/users.json
user alice {
name Alice Example
email alice@example.test
password "LocalDemoPassword123!"
roles authp/user app/member
}
user bob {
name Bob Example
email bob@example.test
password "LocalDemoPassword123!"
roles authp/user
}
}

authentication portal myportal {
enable identity store localdb
crypto key sign-verify {env.AUTHCRUNCH_DEMO_SECRET}
cookie insecure enabled
ui {
links {
"Example app" /app icon "las la-external-link-alt"
}
}
}

authorization policy apppolicy {
set auth url http://localhost:9080/auth/
crypto key verify {env.AUTHCRUNCH_DEMO_SECRET}
allow roles app/member
}
}
}

http://localhost:9080 {
bind 127.0.0.1

route {
redir /auth /auth/ 308

authenticate /auth/* with myportal

@app path /app /app/*
route @app {
authorize with apppolicy
respond "You reached the protected app." 200
}

respond "AuthCrunch demo is running. Open /app to begin." 200
}
}

The two users share a demo password but have different application permissions:

UserPasswordRolesExpected app access
aliceLocalDemoPassword123!authp/user, app/memberAllowed
bobLocalDemoPassword123!authp/userDenied

The local store hashes the configured passwords when creating its user records. The clear-text examples remain in your Caddyfile, so use these credentials only for this demo.

2. Prepare the data and signing key​

mkdir -p data
export AUTHCRUNCH_DEMO_SECRET="$(openssl rand -hex 32)"

The portal signs tokens with this generated secret; the policy uses the same secret to verify them. Keep this terminal open for the next command. {env.AUTHCRUNCH_DEMO_SECRET} reads the variable when AuthCrunch starts.

The store creates data/users.json on first startup. Caddy's own storage is also contained under data/caddy. All these paths are relative to the directory from which you start the process.

3. Check and run​

./bin/authcrunch adapt --adapter caddyfile --config Caddyfile >/dev/null
./bin/authcrunch run --config Caddyfile

Adaptation checks whether Caddy can parse the configuration. The second command starts the server in the foreground and provisions the local user store. Leave it running while you use the browser.

Open http://localhost:9080/app. You should reach the login page. Use localhost consistently; the site is configured for that hostname, and cookies for localhost do not also belong to 127.0.0.1.

4. Sign in as Alice​

  1. Enter alice on the login page and proceed.
  2. Enter LocalDemoPassword123! and submit the password form.
  3. On the portal's Applications page, select Example app.

The app should display:

You reached the protected app.

Alice's token contains app/member, which the policy permits. Bob can also sign in, but his token lacks that role. The next page tests this distinction.

How the configuration fits together​

The global security block defines named building blocks. The site block connects those names to HTTP routes.

ConfigurationPurpose
local identity store localdbCreates the two demo users in a local database
enable identity store localdbGives myportal a login source
authenticate /auth/* with myportalServes the portal under /auth/
set auth url http://localhost:9080/auth/Tells the policy where to send a browser that needs to log in
crypto key sign-verify / crypto key verifyConnects the token issuer and verifier using the same secret
allow roles app/memberRequires the app-specific role
authorize with apppolicyChecks access before the protected response

authp/user permits ordinary portal use. It does not meet this app's app/member rule. Keeping these roles separate lets users sign in without giving every signed-in user access to the application.

The outer route preserves handler order. Inside the /app route, authorize runs before respond; the app's response is reached only after the policy allows the request. The matcher covers both /app and paths below /app/.

cookie insecure enabled allows the demo cookie over HTTP. A deployment with HTTPS should omit this setting. admin off disables Caddy's administration endpoint, and persist_config off disables its saved configuration. Use Ctrl+C to stop this foreground demo; do not use caddy reload with it.

Continue to Verify access before changing the example.