You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add WebID-TLS (mutual TLS / client certificate) authentication to JSS, enabling backend services, CLI tools, and automated agents to authenticate without user interaction.
Background
What is WebID-TLS?
WebID-TLS is a decentralized authentication protocol that uses TLS client certificates:
Client presents X.509 certificate during TLS handshake
Certificate's SubjectAlternativeName (SAN) contains a WebID URI
Server fetches the WebID profile document
Server verifies the certificate's public key matches the one published in the profile
sequenceDiagram
participant C as Client
participant S as JSS Server
participant P as WebID Profile
C->>S: TLS Handshake + Client Cert
Note over S: Extract WebID from SAN
S->>P: Fetch WebID Profile
P-->>S: Profile with cert:key
Note over S: Match modulus + exponent
S-->>C: Authenticated as WebID
Loading
Why Now?
The W3C Linked Web Storage Use Cases group has raised this need for enterprise adoption:
"As a large tax advisory office, I want our existing backend services to authenticate themselves (without user interaction), such that these services can fetch and crunch private data from our clients."
Backend services: Server-to-server communication doesn't need browser UX
IoT/Agents: Automated systems need non-interactive authentication
CLI tools: Developers using curl or custom tools with client certs
Browser Support Note
While browser support for in-browser certificate generation (<keygen>) has been removed from Chrome and deprecated in Firefox, this does not affect server-side WebID-TLS:
Server-to-server: Works perfectly with standard mTLS
Modify src/server.js to request client certificates:
// In createServer, when SSL is enabledif(options.ssl&&options.ssl.key&&options.ssl.cert){consthttpsOptions={key: options.ssl.key,cert: options.ssl.cert,// Enable WebID-TLSrequestCert: options.webidTls||false,// Request client certrejectUnauthorized: false// Don't reject self-signed (we verify via WebID)};// ... create HTTPS server}
Step 2: Create WebID-TLS Auth Module
Create src/auth/webid-tls.js:
import{graph,SPARQLToQuery}from'rdflib';constSPARQL_QUERY=` PREFIX cert: <http://www.w3.org/ns/auth/cert#> SELECT ?webid ?m ?e WHERE { ?webid cert:key ?key . ?key cert:modulus ?m . ?key cert:exponent ?e . }`;/** * Extract WebID from client certificate's SubjectAlternativeName */exportfunctiongetWebIdFromCert(certificate){if(!certificate?.subjectaltname)returnnull;constmatch=certificate.subjectaltname.match(/URI:([^,\s]+)/);returnmatch ? match[1] : null;}/** * Verify certificate public key matches WebID profile */exportasyncfunctionverifyWebIdTls(certificate,webId){if(!certificate.modulus||!certificate.exponent){thrownewError('Certificate missing modulus or exponent');}// Fetch WebID profileconstresponse=awaitfetch(webId,{headers: {'Accept': 'text/turtle, application/ld+json'}});if(!response.ok){thrownewError(`Failed to fetch WebID profile: ${response.status}`);}constbody=awaitresponse.text();constcontentType=response.headers.get('content-type')?.split(';')[0];// Parse profile and find matching keyconstg=graph();// ... parse RDF and run SPARQL queryconstcertModulus=certificate.modulus.toLowerCase();constcertExponent=parseInt(certificate.exponent,16).toString();// Match modulus and exponent from profile// Return true if match found, false otherwise}/** * Middleware to authenticate via WebID-TLS */exportasyncfunctionwebIdTlsAuth(request){constsocket=request.raw?.socket||request.socket;if(!socket?.getPeerCertificate){returnnull;// Not a TLS connection}constcert=socket.getPeerCertificate();if(!cert||Object.keys(cert).length===0){returnnull;// No client certificate}constwebId=getWebIdFromCert(cert);if(!webId){returnnull;// No WebID in certificate}constverified=awaitverifyWebIdTls(cert,webId);returnverified ? webId : null;}
Step 3: Integrate with Auth Flow
In src/auth/token.js, add WebID-TLS as authentication method:
import{webIdTlsAuth}from'./webid-tls.js';exportasyncfunctiongetWebIdFromRequestAsync(request){// Try bearer token firstletwebId=awaitgetWebIdFromToken(request);// Fall back to WebID-TLSif(!webId){webId=awaitwebIdTlsAuth(request);}return{ webId };}
Summary
Add WebID-TLS (mutual TLS / client certificate) authentication to JSS, enabling backend services, CLI tools, and automated agents to authenticate without user interaction.
Background
What is WebID-TLS?
WebID-TLS is a decentralized authentication protocol that uses TLS client certificates:
SubjectAlternativeName(SAN) contains a WebID URIsequenceDiagram participant C as Client participant S as JSS Server participant P as WebID Profile C->>S: TLS Handshake + Client Cert Note over S: Extract WebID from SAN S->>P: Fetch WebID Profile P-->>S: Profile with cert:key Note over S: Match modulus + exponent S-->>C: Authenticated as WebIDWhy Now?
The W3C Linked Web Storage Use Cases group has raised this need for enterprise adoption:
Key drivers:
curlor custom tools with client certsBrowser Support Note
While browser support for in-browser certificate generation (
<keygen>) has been removed from Chrome and deprecated in Firefox, this does not affect server-side WebID-TLS:curl --certworks fineImplementation Guide
Files to Create/Modify
src/auth/webid-tls.jssrc/server.jsrequestCertoption on HTTPS serversrc/config.js--webid-tlsCLI flagStep 1: Server Configuration
Modify
src/server.jsto request client certificates:Step 2: Create WebID-TLS Auth Module
Create
src/auth/webid-tls.js:Step 3: Integrate with Auth Flow
In
src/auth/token.js, add WebID-TLS as authentication method:Step 4: CLI Configuration
Add to
src/config.js:Testing
Manual Testing with curl
Unit Tests
WebID Profile Requirements
For WebID-TLS to work, the WebID profile must contain the certificate's public key:
Use Cases Enabled
curlor custom scriptsReferences
Related