Docs Authentication
Open-swag-go lets you restrict access to your API documentation pages. The DocsAuth struct supports basic auth (username/password) and an API key (passed as a ?key= query parameter) so you can keep internal or staging docs private.
DocsAuth
type DocsAuth struct {
Enabled bool // Enable docs authentication
Username string // Username for basic auth
Password string // Password for basic auth
Realm string // Basic auth realm (default: "API Documentation")
APIKey string // API key, supplied by clients as ?key=<value>
}Basic Auth
Protect your docs with a username and password. Visitors are prompted with a browser login dialog before they can view the documentation.
cfg := openswag.Config{
Info: openswag.Info{
Title: "Internal API",
Version: "1.0.0",
},
DocsAuth: &openswag.DocsAuth{
Enabled: true,
Username: "admin",
Password: "s3cret",
},
}When a visitor navigates to the docs URL, the server responds with a 401 Unauthorized and a WWW-Authenticate: Basic header. The browser shows a native login prompt. After entering valid credentials, the docs load normally. Set Realm to customise the prompt's realm.
Reading credentials from environment variables
Never hard-code credentials. Pull them from the environment at startup:
import "os"
cfg := openswag.Config{
Info: openswag.Info{
Title: "Internal API",
Version: "1.0.0",
},
DocsAuth: &openswag.DocsAuth{
Enabled: true,
Username: os.Getenv("DOCS_USERNAME"),
Password: os.Getenv("DOCS_PASSWORD"),
},
}If either variable is empty (and no APIKey is set), see Misconfiguration below: the docs answer HTTP 500 rather than a login prompt.
API Key Auth
Use an API key instead of username/password. Clients access the docs by appending the key as a ?key= query parameter (e.g. /docs/?key=my-secret-api-key).
cfg := openswag.Config{
Info: openswag.Info{
Title: "Partner API",
Version: "1.0.0",
},
DocsAuth: &openswag.DocsAuth{
Enabled: true,
APIKey: "my-secret-api-key",
},
}Requests without a valid ?key= value receive a 401 Unauthorized response.
DocsAuth: &openswag.DocsAuth{
Enabled: true,
APIKey: os.Getenv("DOCS_API_KEY"),
},Choosing Between Basic Auth and API Key
| Feature | Basic Auth | API Key |
|---|---|---|
| Browser prompt | Yes (native dialog) | No |
| Programmatic access | Requires Base64 encoding | Simple ?key= query param |
| Best for | Internal teams | CI/CD, partner integrations |
When both Username/Password and APIKey are set, either one grants access: a valid API key in the ?key= query string is checked first, then the basic auth credentials. A request that matches neither gets 401 Unauthorized with the basic auth challenge.
Misconfiguration
If Enabled is true but APIKey is empty and Username/Password are not both set, every request to the docs UI and openapi.json gets 500 Internal Server Error with the body DocsAuth enabled but no credentials configured (v1.3.0+). Earlier versions answered 401 for every request, which looked like a wrong password. This usually means an environment variable is missing in that deployment.
Full Example
A complete setup protecting docs with basic auth on a Chi router:
package main
import (
"net/http"
"os"
"github.com/go-chi/chi/v5"
openswag "github.com/gopackx/open-swag-go"
adapter "github.com/gopackx/open-swag-go/adapters/chi"
)
func main() {
docs := openswag.New(openswag.Config{
Info: openswag.Info{
Title: "Internal API",
Version: "1.0.0",
Description: "Protected documentation",
},
DocsAuth: &openswag.DocsAuth{
Enabled: true,
Username: os.Getenv("DOCS_USERNAME"),
Password: os.Getenv("DOCS_PASSWORD"),
},
})
docs.Add(openswag.Endpoint{
Method: "GET",
Path: "/health",
Summary: "Health check",
Responses: openswag.Responses{
200: {Description: "OK"},
},
})
r := chi.NewRouter()
adapter.Mount(r, docs, "/docs")
http.ListenAndServe(":8080", r)
}