Step-by-step instructions for running the Solid Conformance Test Harness against this server.
- Node.js 18+
- Docker
- Port 4000 available
# 1. Kill any existing server on port 4000
fuser -k 4000/tcp 2>/dev/null || true
# 2. Clean data directory
rm -rf data && mkdir data
# 3. Start server with IdP and content negotiation
JSS_PORT=4000 JSS_CONNEG=true JSS_IDP=true node bin/jss.js start &
# 4. Wait for server to be ready
sleep 3
curl -s http://localhost:4000/ > /dev/null && echo "Server ready"
# 5. Create test users
curl -s -X POST http://localhost:4000/.pods \
-H "Content-Type: application/json" \
-d '{"name": "alice", "email": "[email protected]", "password": "alicepassword123"}'
curl -s -X POST http://localhost:4000/.pods \
-H "Content-Type: application/json" \
-d '{"name": "bob", "email": "[email protected]", "password": "bobpassword123"}'
# 6. Create test container (required by CTH)
mkdir -p data/alice/cth-test
# 7. Run authentication tests (assumes test-subjects.ttl and cth.env exist - see Configuration Files below)
docker run --rm --network=host \
-v $(pwd)/test-subjects.ttl:/app/test-subjects.ttl \
--env-file cth.env \
-e SUBJECTS=/app/test-subjects.ttl \
solidproject/conformance-test-harness:latest \
--target="https://github.com/solid/conformance-test-harness/jss" \
--filter="authentication"Create test-subjects.ttl:
@base <https://github.com/solid/conformance-test-harness/> .
@prefix solid-test: <https://github.com/solid/conformance-test-harness/vocab#> .
@prefix doap: <http://usefulinc.com/ns/doap#> .
@prefix earl: <http://www.w3.org/ns/earl#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
<jss>
a earl:Software, earl:TestSubject ;
doap:name "JavaScript Solid Server"@en ;
doap:release <jss#test-subject-release> ;
doap:developer <https://github.com/JavaScriptSolidServer> ;
doap:homepage <https://github.com/JavaScriptSolidServer/JavaScriptSolidServer> ;
doap:description "A minimal, fast, JSON-LD native Solid server."@en ;
doap:programming-language "JavaScript"@en ;
solid-test:skip "acp", "wac", "wac-allow-public" .
<jss#test-subject-release>
doap:revision "0.0.14"@en ;
doap:created "2025-12-27"^^xsd:date .Create cth.env:
SERVER_ROOT=http://localhost:4000
TEST_CONTAINER=/alice/cth-test/
RESOURCE_SERVER_ROOT=http://localhost:4000
LOGIN_ENDPOINT=http://localhost:4000/idp/credentials
SOLID_IDENTITY_PROVIDER=http://localhost:4000/
USERS_ALICE_IDP=http://localhost:4000/
USERS_BOB_IDP=http://localhost:4000/
USERS_ALICE_WEBID=http://localhost:4000/alice/#me
USERS_BOB_WEBID=http://localhost:4000/bob/#me
[email protected]
USERS_ALICE_PASSWORD=alicepassword123
[email protected]
USERS_BOB_PASSWORD=bobpassword123| Variable | Description | Example |
|---|---|---|
SERVER_ROOT |
Server base URL | http://localhost:4000 |
TEST_CONTAINER |
Path to test container | /alice/cth-test/ |
SOLID_IDENTITY_PROVIDER |
IdP issuer URL (with trailing slash) | http://localhost:4000/ |
USERS_ALICE_IDP |
Alice's IdP | http://localhost:4000/ |
USERS_ALICE_WEBID |
Alice's WebID | http://localhost:4000/alice/#me |
USERS_ALICE_USERNAME |
Alice's email | [email protected] |
USERS_ALICE_PASSWORD |
Alice's password | alicepassword123 |
USERS_BOB_IDP |
Bob's IdP | http://localhost:4000/ |
USERS_BOB_WEBID |
Bob's WebID | http://localhost:4000/bob/#me |
USERS_BOB_USERNAME |
Bob's email | [email protected] |
USERS_BOB_PASSWORD |
Bob's password | bobpassword123 |
SUBJECTS |
Path to test-subjects.ttl inside container | /app/test-subjects.ttl |
docker run --rm --network=host \
--env-file cth.env \
-v $(pwd)/test-subjects.ttl:/app/test-subjects.ttl \
-e SUBJECTS=/app/test-subjects.ttl \
solidproject/conformance-test-harness:latest \
--target="https://github.com/solid/conformance-test-harness/jss" \
--filter="authentication"Expected result: 6/6 scenarios passing
docker run --rm --network=host \
--env-file cth.env \
-v $(pwd)/test-subjects.ttl:/app/test-subjects.ttl \
-e SUBJECTS=/app/test-subjects.ttl \
solidproject/conformance-test-harness:latest \
--target="https://github.com/solid/conformance-test-harness/jss"scenarios: 6 | passed: 6 | failed: 0 | time: 0.6349
MustFeatures passed: 1, failed: 0
MustScenarios passed: 6, failed: 0
scenarios: 6 | passed: 4 | failed: 2 | time: 0.7952
Then status 401
status code was: 200, expected: 401, response time in milliseconds: 15
The test container doesn't exist. Create it:
mkdir -p data/alice/cth-testThe WebID profile is not publicly readable. Check that the pod's ACL allows public read on the container itself (but not necessarily on children).
Usually means the IdP isn't returning proper responses. Check:
- Server is running with
--idpflag - Issuer URL has trailing slash
- Users were created with email and password
URL mismatch in DPoP proof validation. Check that issuer URL doesn't have double slashes.
Ensure the server returns JWT access tokens with:
aud: "solid"claim- 3-part JWT format (header.payload.signature)
webidclaim
The server must support:
-
Solid-OIDC Identity Provider
- OIDC discovery at
/.well-known/openid-configuration - JWKS at
/.well-known/jwks.json - Dynamic client registration at
/idp/reg - Credentials endpoint at
/idp/credentials(for programmatic login)
- OIDC discovery at
-
DPoP Token Binding
- RS256 and ES256 algorithms
- Proper
cnf.jktclaim in tokens
-
WWW-Authenticate Header
- 401 responses must include
WWW-Authenticate: DPoP realm="..."
- 401 responses must include
-
Container Creation via PUT
- PUT to path ending with
/creates container
- PUT to path ending with
-
ACL Inheritance
- Children should NOT inherit public read by default
- Only owner permissions should have
acl:default
| Test Suite | Status |
|---|---|
| Authentication | 6/6 passing |
| Protocol (other) | Not yet tested |
| WAC | Skipped |
| ACP | Skipped |