René's URL Explorer Experiment


Title: Support did:key Authentication (LWS10 Spec) · Issue #86 · JavaScriptSolidServer/JavaScriptSolidServer · GitHub

Open Graph Title: Support did:key Authentication (LWS10 Spec) · Issue #86 · JavaScriptSolidServer/JavaScriptSolidServer

X Title: Support did:key Authentication (LWS10 Spec) · Issue #86 · JavaScriptSolidServer/JavaScriptSolidServer

Description: Support did:key Authentication (LWS10 Spec) 🎯 Motivation Backend services and autonomous agents need simple, secure authentication without the X.509 certificate ceremony of WebID-TLS. The W3C LWS protocol suite defines did:key authentica...

Open Graph Description: Support did:key Authentication (LWS10 Spec) 🎯 Motivation Backend services and autonomous agents need simple, secure authentication without the X.509 certificate ceremony of WebID-TLS. The W3C LWS p...

X Description: Support did:key Authentication (LWS10 Spec) 🎯 Motivation Backend services and autonomous agents need simple, secure authentication without the X.509 certificate ceremony of WebID-TLS. The W3C LWS p...

Opengraph URL: https://github.com/JavaScriptSolidServer/JavaScriptSolidServer/issues/86

X: @github

direct link

Domain: github.com


Hey, it has json ld scripts:
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"Support did:key Authentication (LWS10 Spec)","articleBody":"# Support did:key Authentication (LWS10 Spec)\n\n## 🎯 Motivation\n\nBackend services and autonomous agents need simple, secure authentication without the X.509 certificate ceremony of WebID-TLS. The W3C LWS protocol suite defines **did:key authentication** - a modern approach using self-issued JWTs signed with cryptographic keypairs.\n\n**Current pain point:** WebID-TLS requires generating X.509 certificates, embedding public keys in WebID profiles, and configuring TLS. This is heavyweight for simple CLI tools and bot accounts.\n\n**What we want:** Agent generates an ed25519 keypair, derives a `did:key:z6Mk...` identifier, signs a JWT, done. No certificates, no profile updates needed.\n\n## 📋 Background\n\n### What is did:key?\n\nA **Decentralized Identifier** method where the public key IS the identifier:\n\n```\ndid:key:z6MkpTHR8VNsBxYAAWHut2Geadd9jSwuBV8xRoAnwWsdvktH\n         └─────────────────┬──────────────────────┘\n                    base58btc(public key)\n```\n\nThe public key is embedded in the DID itself - no need to fetch it from anywhere.\n\n### How it works\n\n1. **Agent generates keypair** (ed25519 or P-256)\n2. **Derives did:key** from public key\n3. **Creates self-signed JWT** with claims:\n   ```json\n   {\n     \"sub\": \"did:key:z6Mk...\",\n     \"iss\": \"did:key:z6Mk...\",\n     \"client_id\": \"did:key:z6Mk...\",\n     \"aud\": \"https://solid.social/\",\n     \"exp\": 1234567890,\n     \"iat\": 1234567800\n   }\n   ```\n4. **Signs JWT** with private key\n5. **Sends** `Authorization: Bearer \u003cjwt\u003e`\n6. **Server extracts** public key from DID\n7. **Verifies** JWT signature\n\n### Why this is better than WebID-TLS\n\n| WebID-TLS | did:key |\n|-----------|---------|\n| Generate X.509 certificate | Generate keypair |\n| Add cert to WebID profile | DID is self-describing |\n| HTTPS required | Works over HTTP |\n| Complex setup | Simple CLI workflow |\n| RSA (large keys) | Ed25519 (compact) |\n\n## 🔧 Technical Specification\n\n### LWS10 Requirements\n\nPer [W3C LWS Authentication Suite](https://github.com/w3c/lws-protocol/blob/main/lws10-authn-ssi-did-key/index.html):\n\n**Required JWT Claims:**\n- `sub`, `iss`, `client_id`: All MUST use same `did:key:` URI\n- `aud`: MUST include target authorization server\n- `exp`: Token expiration timestamp\n- `iat`: Token creation timestamp\n- `alg`: Cannot be \"none\"\n\n**Validation:**\n1. Extract public key from `did:key` identifier (per [DID Key spec](https://w3c-ccg.github.io/did-method-key/))\n2. Verify JWT signature using extracted key (RFC 7515)\n3. Validate claims (timestamps, audience, triple equality of sub/iss/client_id)\n4. Optional: Allow clock skew tolerance (±5 min)\n\n### Supported Key Types\n\n- **Ed25519** (recommended): `did:key:z6Mk...` (multicodec `0xed`)\n- **P-256**: `did:key:zDna...` (multicodec `0x1200`)\n- **secp256k1**: `did:key:zQ3s...` (multicodec `0xe7`)\n\n## 🛠️ Implementation Plan\n\n### Phase 1: Core Authentication (~2-3 hours)\n\n**New file:** `src/auth/did-key.js`\n\n```javascript\nimport { jwtVerify, importJWK } from 'jose';\nimport { base58btc } from 'multiformats/bases/base58';\nimport * as ed25519 from '@noble/ed25519';\n\n/**\n * Verify did:key JWT authentication\n * @param {string} token - Bearer token\n * @param {string} audience - Expected audience (server URL)\n * @returns {string} - WebID derived from did:key\n */\nexport async function verifyDidKeyJWT(token, audience) {\n  // Decode without verification to get DID\n  const { payload } = await jwtVerify(token, async (header, token) =\u003e {\n    const did = token.payload.sub;\n    \n    if (!did?.startsWith('did:key:')) {\n      throw new Error('Invalid DID format');\n    }\n    \n    // Extract public key from did:key\n    const publicKey = await didKeyToPublicKey(did);\n    return publicKey;\n  });\n  \n  // Validate LWS10 constraints\n  if (payload.sub !== payload.iss || payload.sub !== payload.client_id) {\n    throw new Error('sub, iss, and client_id must be identical');\n  }\n  \n  if (!Array.isArray(payload.aud) || !payload.aud.includes(audience)) {\n    throw new Error('Invalid audience');\n  }\n  \n  if (!payload.exp || !payload.iat) {\n    throw new Error('Missing exp or iat claims');\n  }\n  \n  // Return WebID (in our case, same as DID for now)\n  return payload.sub;\n}\n\n/**\n * Extract public key from did:key identifier\n * Supports ed25519, P-256, secp256k1\n */\nasync function didKeyToPublicKey(did) {\n  const multibaseKey = did.replace('did:key:', '');\n  const bytes = base58btc.decode(multibaseKey);\n  \n  // First 2 bytes are multicodec prefix\n  const codec = (bytes[0] \u003c\u003c 8) | bytes[1];\n  const publicKeyBytes = bytes.slice(2);\n  \n  switch (codec) {\n    case 0xed: // Ed25519\n      return await ed25519PublicKeyToJWK(publicKeyBytes);\n    case 0x1200: // P-256\n      return await p256PublicKeyToJWK(publicKeyBytes);\n    default:\n      throw new Error(`Unsupported key type: 0x${codec.toString(16)}`);\n  }\n}\n\nasync function ed25519PublicKeyToJWK(publicKeyBytes) {\n  return {\n    kty: 'OKP',\n    crv: 'Ed25519',\n    x: Buffer.from(publicKeyBytes).toString('base64url')\n  };\n}\n```\n\n**Update:** `src/auth/middleware.js`\n\n```javascript\nimport { verifyDidKeyJWT } from './did-key.js';\n\n// In authorize() function, add did:key support:\nif (authHeader?.startsWith('Bearer ')) {\n  const token = authHeader.slice(7);\n  \n  try {\n    // Try did:key JWT first\n    const webId = await verifyDidKeyJWT(token, request.hostname);\n    return { authorized: true, webId };\n  } catch (didKeyErr) {\n    // Fall through to existing token/OIDC validation\n  }\n}\n```\n\n### Phase 2: CLI Tool Support (~1 hour)\n\n**New command:** `jss auth generate-did-key`\n\n```javascript\n// bin/jss.js\nprogram\n  .command('auth')\n  .command('generate-did-key')\n  .description('Generate did:key credentials for agent authentication')\n  .action(async () =\u003e {\n    const { privateKey, publicKey } = await ed25519.utils.randomPrivateKey();\n    const did = await publicKeyToDidKey(publicKey);\n    \n    console.log('Generated did:key credentials:');\n    console.log(`\\nDID: ${did}`);\n    console.log(`Private Key (hex): ${Buffer.from(privateKey).toString('hex')}`);\n    console.log('\\nSave private key securely. Use it to sign JWTs for authentication.');\n  });\n```\n\n### Phase 3: Documentation (~30 min)\n\nAdd to README.md:\n\n```markdown\n### did:key Authentication (Agents \u0026 Bots)\n\nFor autonomous agents, CLI tools, and backend services:\n\n**Generate credentials:**\n```bash\njss auth generate-did-key\n# DID: did:key:z6MkpTHR8VNsBxYAAWHut2Geadd9jSwuBV8xRoAnwWsdvktH\n# Private Key: 9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60\n```\n\n**Create JWT and authenticate:**\n```javascript\nimport { SignJWT } from 'jose';\nimport * as ed25519 from '@noble/ed25519';\n\nconst privateKeyHex = '9d61b19...';\nconst did = 'did:key:z6Mk...';\n\nconst jwt = await new SignJWT({})\n  .setProtectedHeader({ alg: 'EdDSA' })\n  .setSubject(did)\n  .setIssuer(did)\n  .setAudience('https://solid.social/')\n  .claim('client_id', did)\n  .setExpirationTime('1h')\n  .setIssuedAt()\n  .sign(privateKeyFromHex(privateKeyHex));\n\n// Use JWT\nconst res = await fetch('https://solid.social/alice/private/', {\n  headers: { 'Authorization': `Bearer ${jwt}` }\n});\n```\n\n**Benefits:**\n- No certificates or profile setup\n- Self-describing identifiers\n- Standard JWT format\n- Works over HTTP or HTTPS\n```\n\n### Phase 4: Testing (~1 hour)\n\n**New file:** `test/did-key.test.js`\n\n```javascript\nimport { describe, it } from 'node:test';\nimport assert from 'node:assert';\nimport { SignJWT, generateKeyPair } from 'jose';\nimport { verifyDidKeyJWT } from '../src/auth/did-key.js';\n\ndescribe('did:key Authentication', () =\u003e {\n  it('should verify valid did:key JWT', async () =\u003e {\n    const { publicKey, privateKey } = await generateKeyPair('EdDSA');\n    const did = await publicKeyToDidKey(publicKey);\n    \n    const jwt = await new SignJWT({})\n      .setProtectedHeader({ alg: 'EdDSA' })\n      .setSubject(did)\n      .setIssuer(did)\n      .setAudience('https://example.com/')\n      .claim('client_id', did)\n      .setExpirationTime('1h')\n      .setIssuedAt()\n      .sign(privateKey);\n    \n    const webId = await verifyDidKeyJWT(jwt, 'https://example.com/');\n    assert.strictEqual(webId, did);\n  });\n  \n  it('should reject mismatched sub/iss/client_id', async () =\u003e {\n    // Test validation logic\n  });\n  \n  it('should reject invalid audience', async () =\u003e {\n    // Test audience validation\n  });\n});\n```\n\n## 📦 Dependencies\n\n**New:**\n- `multiformats` - Multibase/multicodec decoding\n- `@noble/ed25519` - Ed25519 crypto operations\n\n**Existing (already installed):**\n- `jose` - JWT verification\n\n## 🎯 Use Cases\n\n1. **CLI tools** - `jss-cli` authenticates to remote pods\n2. **Backend bots** - Automated agents that manage resources\n3. **Server-to-server** - Microservices accessing pod data\n4. **IoT devices** - Resource-constrained agents (Ed25519 is tiny)\n5. **LWS protocol compliance** - Interop with other LWS implementations\n\n## 🔗 References\n\n- [W3C LWS Authentication Suite](https://github.com/w3c/lws-protocol/blob/main/lws10-authn-ssi-did-key/index.html)\n- [DID Key Method Spec](https://w3c-ccg.github.io/did-method-key/)\n- [Multicodec Table](https://github.com/multiformats/multicodec/blob/master/table.csv)\n- [RFC 7515 - JSON Web Signature](https://datatracker.ietf.org/doc/html/rfc7515)\n\n## 🚀 Acceptance Criteria\n\n- [ ] Verify Ed25519 did:key JWTs\n- [ ] Support P-256 did:key JWTs\n- [ ] Validate all LWS10 required claims\n- [ ] CLI command to generate did:key credentials\n- [ ] Integration with existing auth middleware\n- [ ] Tests covering validation rules\n- [ ] Documentation with examples\n- [ ] No breaking changes to existing auth methods\n\n---\n\n**Estimated effort:** 4-5 hours total\n**Priority:** Medium (nice alternative to WebID-TLS)\n**Dependencies:** None (adds to existing auth stack)\n","author":{"url":"https://github.com/melvincarvalho","@type":"Person","name":"melvincarvalho"},"datePublished":"2026-01-14T14:31:23.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":0},"url":"https://github.com/86/JavaScriptSolidServer/issues/86"}

route-pattern/_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format)
route-controllervoltron_issues_fragments
route-actionissue_layout
fetch-noncev2:109a07ba-27cb-c34c-5d22-b4646907a18f
current-catalog-service-hash81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114
request-idAF44:8B50E:BE52A42:F6B4895:6976FE0B
html-safe-nonce0aa8631346640e2fd2171c832a7c15359cb204a5ca8d1834f773f26f8722d762
visitor-payloadeyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJBRjQ0OjhCNTBFOkJFNTJBNDI6RjZCNDg5NTo2OTc2RkUwQiIsInZpc2l0b3JfaWQiOiIyNjgxNTA1OTExODI1NDMyMDc1IiwicmVnaW9uX2VkZ2UiOiJpYWQiLCJyZWdpb25fcmVuZGVyIjoiaWFkIn0=
visitor-hmac19ce88c0b3827bda32e6e3b5f6ccb5aca521c24ed7e1e55041f4e95b82550dbe
hovercard-subject-tagissue:3813463515
github-keyboard-shortcutsrepository,issues,copilot
google-site-verificationApib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I
octolytics-urlhttps://collector.github.com/github/collect
analytics-location///voltron/issues_fragments/issue_layout
fb:app_id1401488693436528
apple-itunes-appapp-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/JavaScriptSolidServer/JavaScriptSolidServer/86/issue_layout
twitter:imagehttps://opengraph.githubassets.com/c4a32ba94135f7ba31fbf50b2d8880d1df57d3fd5bd701b6db93fb6e9047436c/JavaScriptSolidServer/JavaScriptSolidServer/issues/86
twitter:cardsummary_large_image
og:imagehttps://opengraph.githubassets.com/c4a32ba94135f7ba31fbf50b2d8880d1df57d3fd5bd701b6db93fb6e9047436c/JavaScriptSolidServer/JavaScriptSolidServer/issues/86
og:image:altSupport did:key Authentication (LWS10 Spec) 🎯 Motivation Backend services and autonomous agents need simple, secure authentication without the X.509 certificate ceremony of WebID-TLS. The W3C LWS p...
og:image:width1200
og:image:height600
og:site_nameGitHub
og:typeobject
og:author:usernamemelvincarvalho
hostnamegithub.com
expected-hostnamegithub.com
None01d198479908d09a841b2febe8eb105a81af2af7d81830960fe0971e1f4adc09
turbo-cache-controlno-preview
go-importgithub.com/JavaScriptSolidServer/JavaScriptSolidServer git https://github.com/JavaScriptSolidServer/JavaScriptSolidServer.git
octolytics-dimension-user_id205442424
octolytics-dimension-user_loginJavaScriptSolidServer
octolytics-dimension-repository_id958025407
octolytics-dimension-repository_nwoJavaScriptSolidServer/JavaScriptSolidServer
octolytics-dimension-repository_publictrue
octolytics-dimension-repository_is_forkfalse
octolytics-dimension-repository_network_root_id958025407
octolytics-dimension-repository_network_root_nwoJavaScriptSolidServer/JavaScriptSolidServer
turbo-body-classeslogged-out env-production page-responsive
disable-turbofalse
browser-stats-urlhttps://api.github.com/_private/browser/stats
browser-errors-urlhttps://api.github.com/_private/browser/errors
releasef752335dbbea672610081196a1998e39aec5e14b
ui-targetfull
theme-color#1e2327
color-schemelight dark

Links:

Skip to contenthttps://github.com/JavaScriptSolidServer/JavaScriptSolidServer/issues/86#start-of-content
https://github.com/
Sign in https://github.com/login?return_to=https%3A%2F%2Fgithub.com%2FJavaScriptSolidServer%2FJavaScriptSolidServer%2Fissues%2F86
GitHub CopilotWrite better code with AIhttps://github.com/features/copilot
GitHub SparkBuild and deploy intelligent appshttps://github.com/features/spark
GitHub ModelsManage and compare promptshttps://github.com/features/models
MCP RegistryNewIntegrate external toolshttps://github.com/mcp
ActionsAutomate any workflowhttps://github.com/features/actions
CodespacesInstant dev environmentshttps://github.com/features/codespaces
IssuesPlan and track workhttps://github.com/features/issues
Code ReviewManage code changeshttps://github.com/features/code-review
GitHub Advanced SecurityFind and fix vulnerabilitieshttps://github.com/security/advanced-security
Code securitySecure your code as you buildhttps://github.com/security/advanced-security/code-security
Secret protectionStop leaks before they starthttps://github.com/security/advanced-security/secret-protection
Why GitHubhttps://github.com/why-github
Documentationhttps://docs.github.com
Bloghttps://github.blog
Changeloghttps://github.blog/changelog
Marketplacehttps://github.com/marketplace
View all featureshttps://github.com/features
Enterpriseshttps://github.com/enterprise
Small and medium teamshttps://github.com/team
Startupshttps://github.com/enterprise/startups
Nonprofitshttps://github.com/solutions/industry/nonprofits
App Modernizationhttps://github.com/solutions/use-case/app-modernization
DevSecOpshttps://github.com/solutions/use-case/devsecops
DevOpshttps://github.com/solutions/use-case/devops
CI/CDhttps://github.com/solutions/use-case/ci-cd
View all use caseshttps://github.com/solutions/use-case
Healthcarehttps://github.com/solutions/industry/healthcare
Financial serviceshttps://github.com/solutions/industry/financial-services
Manufacturinghttps://github.com/solutions/industry/manufacturing
Governmenthttps://github.com/solutions/industry/government
View all industrieshttps://github.com/solutions/industry
View all solutionshttps://github.com/solutions
AIhttps://github.com/resources/articles?topic=ai
Software Developmenthttps://github.com/resources/articles?topic=software-development
DevOpshttps://github.com/resources/articles?topic=devops
Securityhttps://github.com/resources/articles?topic=security
View all topicshttps://github.com/resources/articles
Customer storieshttps://github.com/customer-stories
Events & webinarshttps://github.com/resources/events
Ebooks & reportshttps://github.com/resources/whitepapers
Business insightshttps://github.com/solutions/executive-insights
GitHub Skillshttps://skills.github.com
Documentationhttps://docs.github.com
Customer supporthttps://support.github.com
Community forumhttps://github.com/orgs/community/discussions
Trust centerhttps://github.com/trust-center
Partnershttps://github.com/partners
GitHub SponsorsFund open source developershttps://github.com/sponsors
Security Labhttps://securitylab.github.com
Maintainer Communityhttps://maintainers.github.com
Acceleratorhttps://github.com/accelerator
Archive Programhttps://archiveprogram.github.com
Topicshttps://github.com/topics
Trendinghttps://github.com/trending
Collectionshttps://github.com/collections
Enterprise platformAI-powered developer platformhttps://github.com/enterprise
GitHub Advanced SecurityEnterprise-grade security featureshttps://github.com/security/advanced-security
Copilot for BusinessEnterprise-grade AI featureshttps://github.com/features/copilot/copilot-business
Premium SupportEnterprise-grade 24/7 supporthttps://github.com/premium-support
Pricinghttps://github.com/pricing
Search syntax tipshttps://docs.github.com/search-github/github-code-search/understanding-github-code-search-syntax
documentationhttps://docs.github.com/search-github/github-code-search/understanding-github-code-search-syntax
Sign in https://github.com/login?return_to=https%3A%2F%2Fgithub.com%2FJavaScriptSolidServer%2FJavaScriptSolidServer%2Fissues%2F86
Sign up https://github.com/signup?ref_cta=Sign+up&ref_loc=header+logged+out&ref_page=%2F%3Cuser-name%3E%2F%3Crepo-name%3E%2Fvoltron%2Fissues_fragments%2Fissue_layout&source=header-repo&source_repo=JavaScriptSolidServer%2FJavaScriptSolidServer
Reloadhttps://github.com/JavaScriptSolidServer/JavaScriptSolidServer/issues/86
Reloadhttps://github.com/JavaScriptSolidServer/JavaScriptSolidServer/issues/86
Reloadhttps://github.com/JavaScriptSolidServer/JavaScriptSolidServer/issues/86
JavaScriptSolidServer https://github.com/JavaScriptSolidServer
JavaScriptSolidServerhttps://github.com/JavaScriptSolidServer/JavaScriptSolidServer
Notifications https://github.com/login?return_to=%2FJavaScriptSolidServer%2FJavaScriptSolidServer
Fork 4 https://github.com/login?return_to=%2FJavaScriptSolidServer%2FJavaScriptSolidServer
Star 4 https://github.com/login?return_to=%2FJavaScriptSolidServer%2FJavaScriptSolidServer
Code https://github.com/JavaScriptSolidServer/JavaScriptSolidServer
Issues 59 https://github.com/JavaScriptSolidServer/JavaScriptSolidServer/issues
Pull requests 6 https://github.com/JavaScriptSolidServer/JavaScriptSolidServer/pulls
Actions https://github.com/JavaScriptSolidServer/JavaScriptSolidServer/actions
Projects 0 https://github.com/JavaScriptSolidServer/JavaScriptSolidServer/projects
Security 0 https://github.com/JavaScriptSolidServer/JavaScriptSolidServer/security
Insights https://github.com/JavaScriptSolidServer/JavaScriptSolidServer/pulse
Code https://github.com/JavaScriptSolidServer/JavaScriptSolidServer
Issues https://github.com/JavaScriptSolidServer/JavaScriptSolidServer/issues
Pull requests https://github.com/JavaScriptSolidServer/JavaScriptSolidServer/pulls
Actions https://github.com/JavaScriptSolidServer/JavaScriptSolidServer/actions
Projects https://github.com/JavaScriptSolidServer/JavaScriptSolidServer/projects
Security https://github.com/JavaScriptSolidServer/JavaScriptSolidServer/security
Insights https://github.com/JavaScriptSolidServer/JavaScriptSolidServer/pulse
New issuehttps://github.com/login?return_to=https://github.com/JavaScriptSolidServer/JavaScriptSolidServer/issues/86
New issuehttps://github.com/login?return_to=https://github.com/JavaScriptSolidServer/JavaScriptSolidServer/issues/86
Support did:key Authentication (LWS10 Spec)https://github.com/JavaScriptSolidServer/JavaScriptSolidServer/issues/86#top
https://github.com/melvincarvalho
https://github.com/melvincarvalho
melvincarvalhohttps://github.com/melvincarvalho
on Jan 14, 2026https://github.com/JavaScriptSolidServer/JavaScriptSolidServer/issues/86#issue-3813463515
W3C LWS Authentication Suitehttps://github.com/w3c/lws-protocol/blob/main/lws10-authn-ssi-did-key/index.html
DID Key spechttps://w3c-ccg.github.io/did-method-key/
W3C LWS Authentication Suitehttps://github.com/w3c/lws-protocol/blob/main/lws10-authn-ssi-did-key/index.html
DID Key Method Spechttps://w3c-ccg.github.io/did-method-key/
Multicodec Tablehttps://github.com/multiformats/multicodec/blob/master/table.csv
RFC 7515 - JSON Web Signaturehttps://datatracker.ietf.org/doc/html/rfc7515
https://github.com
Termshttps://docs.github.com/site-policy/github-terms/github-terms-of-service
Privacyhttps://docs.github.com/site-policy/privacy-policies/github-privacy-statement
Securityhttps://github.com/security
Statushttps://www.githubstatus.com/
Communityhttps://github.community/
Docshttps://docs.github.com/
Contacthttps://support.github.com?tags=dotcom-footer

Viewport: width=device-width


URLs of crawlers that visited me.