Authentication with OpenID Connect
Using a public OIDC provider
You can instruct smallweb to authenticate users using OpenID connect. The easiest to get started is to use Lastlogin, a public OIDC provider that do not require a registration process.
Firt, set the oidc.issuer
field in your smallweb config:
// $SMALLWEB_DIR/.smallweb/config.json
{
"domain": "example.com",
"oidc": {
"issuer": "https://lastlogin.net"
},
"apps": {
"demo": {
"private": true
}
}
}
The next time you'll access demo.example.com
, you'll need to confirm your email address using lastlogin. Once you do that, you'll be redirected to your app.
You can access the email of the current user using the Remote-Email
header:
// $SMALLWEB_DIR/demo/main.ts
export default {
fetch(req: Request) {
const email = req.headers.get("Remote-Email");
return new Response(`Hello, ${email}`, {
headers: {
"Content-Type": "text/plain",
},
});
}
}
If you want to only authorize a fixed set of users, you can set the authorizedEmails
property (either in globally or per app):
{
"domain": "example.com",
"oidc": {
"issuer": "https://lastlogin.net"
},
// globally
"authorizedEmails": [
"[email protected]"
],
"apps": {
"demo": {
// per app
"authorizedEmails": [
"[email protected]"
],
"private": true
}
}
}
The instructions above also apply to openid connect groups (using the Remote-Groups
header and the authorizedGroups
property).
If you want to only protect specific routes, set the privateRoutes
and publicRoutes
array. Smallweb uses doublestar to check request paths against the global patterns
{
"domain": "example.com",
"oidc": {
"issuer": "https://lastlogin.net"
},
"apps": {
"demo": {
"private": true,
"publicRoutes": [
"/public/**"
]
},
"example": {
"privateRoutes": [
"/private/**"
]
}
}
}
Hosting your own OIDC provider from smallweb
Nothing stops you from using an internal url as the issuer !
{
"domain": "example.com",
"oidc": {
"issuer": "https://auth.example.com"
},
"apps": {
"demo": {
"private": true
}
}
}
In this case, the auth
app should exposes an OIDC provider. I recommend using openauth.
WARNING
Openauth does not support beeing used as an OIDC provider yet, so I've built a wrapper to add support for it. Make sure to follow this issue for official support.
// ~/smallweb/auth/main.ts
import { issuer } from "npm:@openauthjs/openauth";
import { oidc } from "jsr:@pomdtr/openauth-oidc";
import { MemoryStorage } from "npm:@openauthjs/openauth/storage/memory";
const storage = new MemoryStorage({
persist: "./data/db.json",
})
const iss = issuer({
storage,
// ...
})
export default oidc(iss, storage);
Openauth support a bunch of issuers (Google, Github, etc), refer to their documentation for more information.
Smallweb use the app origin as the client_id
, and no client_secret
. You can read more about the logic behind these choices at https://lastlogin.net/developers/.