This is an example issuer built with rocket
and oidc4vci-rs
.
Credential types supported:
- JWT
- JSONLD
Endpoints available:
-
GET /
: to access a pre-authorized code in QRCode or link format, nopin
support. -
POST /issuer/preauth?<query..>
: to obtain a pre-authorized code with a specifictype
,pin
anduser_id
. -
GET /.well-known/openid-configuration
: to obtain the OIDC configuration. -
GET /jwks
: to obtain JWKs used by the server. -
POST /token
: to exchange the pre-authorized code by an access token. -
POST /credential
: to issue a credential, requiresAuthorization
provided by the previous step.
- Add JSONLD support;
- Add more configuration options;
- Supported credential types;
- Access token expiration time;
- External credential provider to easily change the hard-coded
OpenBadgeCredential
;
A .env
file must be created with the following variables:
ISSUER=http://localhost:9000
JWK='{"kty":"OKP","crv":"Ed25519","x":"<redacted>","d":"<redacted>"}'
JWE_SECRET=<redacted>
The ISSUER
will be used to fill the oidc-configuration
endpoint and
inside the credential in the .issuer.url
field.
The JWK
will be used to create a DID and sign the credentials.
There are several ways to create your JWK. There are online tools,
but those are of course not feasible for production use. Another way is to use jwk-generator
,
java -jar json-web-key-generator.jar -t EC -c P-256 -u sig
or openssl with a pem-jwk converter.
The JWE_SECRET
will be used to support PIN enabled Issuance Request,
this password will be used with PBES2_HS512_A256KW
JWE
encryption.
The docker-compose
file can be used to run the required Redis instance.
docker compose up -d redis
If you want to point to a different instance of Redis, you can add the
URL to the following variable in the .env
file:
REDIS_URL=redis://127.0.0.1/
The rust-toolchain.toml
file is configured to use Rust nightly
.
If that doesn't work, you can add the override manually with:
rustup override set nightly
In the Rocket.toml
, you can change the port that the server will use as shown below:
[debug]
port = 8080
For more information on other server options provided by Rocket
please refer to its documentation.
Once the database instance is up and running you have to start the Rocket-based web service itself:
cargo run
The following commented bash script is an example of the format and calls made to this issuer.
#!/bin/bash
# Change URL according to the server you're testing with
url=http://localhost:9000
# If `uuidgen` is not present in your environment, just substitute by a hardcoded value
uuid=`uuidgen`
preauth=$(curl -s -X POST $url/issuer/preauth\?type\=OpenBadgeCredential\&user_id\=$uuid)
# This requires `jq` to extract the `access_token` value from the JSON, could be done manually or in other ways
access_token=$(curl -s -X POST $url/token \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d "grant_type=urn:ietf:params:oauth:grant-type:pre-authorized_code&pre-authorized_code=$preauth"\
| jq -r '.access_token')
# Replace `proof.jwt` to one generated by your client.
# In this example, the `jwt` uses `did:key:z6MkwEGcHQYdp8dfiM34VSnEdVRMF9TNRECnhvbRHPCBqQr9`
# has a `http://localhost:9000` audience and a one year duration to facilitate testing.
# THEY ARE NOT INTENDED AS EXAMPLE PRODUCTION VALUES
# `type` and `format` might differ if working with other issuers.
# Only `jwt` is supported for `proof.proof_type` at the moment.
credential_request=$(cat <<EOF
{
"type": "OpenBadgeCredential",
"format": "ldp_vc",
"proof": {
"proof_type": "jwt",
"jwt": "eyJhbGciOiJFZERTQSIsImtpZCI6ImRpZDprZXk6ejZNa3dFR2NIUVlkcDhkZmlNMzRWU25FZFZSTUY5VE5SRUNuaHZiUkhQQ0JxUXI5In0.eyJpc3MiOiJjb20uc3BydWNlaWQuY3JlZGlibGUiLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjkwMDAiLCJpYXQiOiIyMDIyLTEwLTIwVDE5OjA5OjEwLjcyMjM0NFoiLCJleHAiOiIyMDIzLTEwLTE5VDE5OjA5OjEwLjcyMTcwMFoiLCJqdGkiOiJHc1RFUkZWNEhkTFRGRUE4NWJxZ2FEbzl1WEFrVnJxViJ9.hMqRNt3Ld54FpwN_SmLd6E0wGUZ3-LOaoMWMuVcvZidrZtUGxTt2WsP0jQ0KbqOWruCl0vqD7jTiVJUCyMnZCQ"
}
}
EOF
)
curl -X POST $url/credential \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer $access_token" \
-d "$credential_request"