JavaScript¶
Browser · fetch
Getting a token silently in the browser¶
Use this in a frontend that should authenticate as one of your devices
without any login UI — the device's client certificate, once installed in
the OS/browser keychain, proves its identity during the TLS handshake for
the /auth/token request itself.
/**
* Drop this into any other project's frontend to get an Obsidian access
* token silently, then call your own API with it.
*
* Requires the device's client certificate to already be installed in the
* OS/browser keychain (see README "Installing a device certificate").
*
* Caveat — browsers show a certificate-picker dialog the first time a site
* requests a client cert (there is no JS API to suppress it). It is
* per-browser-profile and one-time until the cert is deleted or the profile
* is reset — not a per-request prompt. On managed devices you can pre-select
* it automatically via the browser's AutoSelectCertificateForUrls enterprise
* policy; see the README for the exact policy JSON.
*/
const OBSIDIAN_ISSUER = "https://auth.jyjwong.com"; // set to your Obsidian deployment
async function getAccessToken() {
const response = await fetch(`${OBSIDIAN_ISSUER}/auth/token`, {
method: "POST",
});
if (!response.ok) {
throw new Error(`Obsidian token request failed: ${response.status}`);
}
const { access_token, expires_in } = await response.json();
return { access_token, expires_in };
}
async function callProtectedApi() {
const { access_token } = await getAccessToken();
const response = await fetch("https://api.jyjwong.com/reports", {
headers: { Authorization: `Bearer ${access_token}` },
});
return response.json();
}
Call getAccessToken() before hitting your own API, then attach the token
as a normal Authorization: Bearer header — exactly like the
callProtectedApi() helper above does.
The certificate picker is one-time, not per-request
The first time a browser profile visits a site that requests a client certificate, it shows a picker dialog — there's no JS API to suppress it. It's per browser profile, not per request: once selected, it's remembered until the certificate is removed or the profile is reset.
On a device you manage yourself, some browsers support pre-selecting
the certificate for a given origin via an enterprise policy (Chrome's
AutoSelectCertificateForUrls), removing the picker entirely. See the
repository README
for the exact policy JSON — it's a convenience, not a requirement.
Prerequisite: installing the device certificate¶
This snippet assumes the browser already has a client certificate for this
device installed. That's a one-time, per-device setup step — bundling the
key + cert into a .p12 file and importing it into the OS/browser keychain
— covered in the
README's "Installing a device certificate" section.
It isn't part of the frontend code itself, so it isn't duplicated here.