Adding Authentication to Azure Static Web Apps (Hugo)#

This guide covers how to lock your Hugo site behind a login using Azure Static Web Apps (SWA) built-in authentication, and restrict access to selected users only.


Prerequisites#

  • Hugo site deployed to Azure Static Web Apps via GitHub Actions
  • Azure account with your Static Web App resource provisioned
  • static/staticwebapp.config.json file in your Hugo project

How It Works#

Azure SWA handles authentication at the infrastructure level — no backend code required. The staticwebapp.config.json file controls which routes are protected and which identity provider handles login.

User visits site
  → Not authenticated → redirected to login page
  → Logs in with Microsoft / GitHub
  → Redirected back → access granted (if role matches)

Option 1 — Microsoft / Entra ID Login (Free Tier)#

The simplest option. Works on the free plan, no OAuth app registration needed.

1. Create the config file#

Place this at static/staticwebapp.config.json in your Hugo project:

{
  "routes": [
    {
      "route": "/*",
      "allowedRoles": ["member"]
    }
  ],
  "responseOverrides": {
    "401": {
      "statusCode": 302,
      "redirect": "/.auth/login/aad"
    }
  }
}

Hugo copies everything in static/ to the output root, so this file will be at the site root after build.

2. Invite specific users#

  1. Go to Azure Portal → your Static Web App → Settings → Role Management
  2. Click Invite
  3. Select Azure Active Directory as the provider
  4. Enter the user’s email address
  5. Assign the role member
  6. Send them the generated invite link — they must click it once to activate

Anyone who logs in but has not been invited as member will be blocked.


Option 2 — GitHub Login (Standard Plan ~$9/mo)#

Use this if your users already have GitHub accounts.

1. Create a GitHub OAuth App#

  1. Go to GitHub → Settings → Developer Settings → OAuth Apps → New OAuth App
  2. Fill in:
    • Application name: anything (e.g. my-hugo-site)
    • Homepage URL: https://your-site.azurestaticapps.net
    • Authorization callback URL: https://your-site.azurestaticapps.net/.auth/login/github/callback
  3. Click Register application
  4. Copy the Client ID and generate a Client Secret

2. Add secrets to Azure#

In the Azure Portal → your Static Web App → Settings → Configuration → Application Settings, add:

NameValue
GITHUB_CLIENT_IDyour GitHub OAuth App client ID
GITHUB_CLIENT_SECRETyour GitHub OAuth App client secret

3. Create the config file#

{
  "auth": {
    "identityProviders": {
      "github": {
        "registration": {
          "clientIdSettingName": "GITHUB_CLIENT_ID",
          "clientSecretSettingName": "GITHUB_CLIENT_SECRET"
        }
      }
    }
  },
  "routes": [
    {
      "route": "/*",
      "allowedRoles": ["member"]
    }
  ],
  "responseOverrides": {
    "401": {
      "statusCode": 302,
      "redirect": "/.auth/login/github"
    }
  }
}

4. Invite specific users#

  1. Go to Azure Portal → your Static Web App → Settings → Role Management
  2. Click Invite
  3. Select GitHub as the provider
  4. Enter the user’s GitHub username (not email)
  5. Assign the role member
  6. Send them the invite link to activate

Add a logout link anywhere in your Hugo templates:

<a href="/.auth/logout">Logout</a>

Or add a friendly route in your config:

{
  "routes": [
    { "route": "/logout", "redirect": "/.auth/logout" },
    { "route": "/*", "allowedRoles": ["member"] }
  ]
}

Checking Who Is Logged In#

SWA exposes a built-in endpoint at /.auth/me that returns the current user’s info:

const response = await fetch('/.auth/me');
const { clientPrincipal } = await response.json();
console.log(clientPrincipal);
// { identityProvider, userId, userDetails, userRoles }

You can use this in Hugo’s JavaScript to show/hide content or display the username.


Complete staticwebapp.config.json Reference#

{
  "auth": {
    "identityProviders": {
      "github": {
        "registration": {
          "clientIdSettingName": "GITHUB_CLIENT_ID",
          "clientSecretSettingName": "GITHUB_CLIENT_SECRET"
        }
      }
    }
  },
  "routes": [
    {
      "route": "/logout",
      "redirect": "/.auth/logout"
    },
    {
      "route": "/*",
      "allowedRoles": ["member"]
    }
  ],
  "responseOverrides": {
    "401": {
      "statusCode": 302,
      "redirect": "/.auth/login/github"
    }
  }
}

Comparison#

Microsoft (AAD)GitHub
Azure planFreeStandard (~$9/mo)
Login withMicrosoft accountGitHub account
Invite byEmail addressGitHub username
OAuth app setupNot requiredRequired
Best forWork/org usersDeveloper teams

Troubleshooting#

Users see a 401 after logging in → They authenticated successfully but haven’t been invited with the member role. Go to Role Management and invite them.

Config changes not taking effect → Make sure staticwebapp.config.json is in the static/ folder (not the root of the repo). Hugo must copy it to public/ during build.

GitHub OAuth redirect error → Double-check the callback URL in your GitHub OAuth App matches exactly: https://your-site.azurestaticapps.net/.auth/login/github/callback

Custom auth toggle greyed out in portal → Check GitHub Organization Settings → Third-party Access → OAuth App Policy and ensure Azure SWA is allowed.