Lab sandbox
Open Finance sandbox
Chile has the regulation and no public place to test against it. This is one, with the recipe to plug your own implementation in.
What you can exercise here
Everything the Technical Annex asks for on the wire: discovery against a directory, dynamic registration from a signed software statement, mandatory PAR carrying a signed and encrypted request object, mTLS with certificate-bound tokens, consent with its full detail and a second factor, and authorization_details reaching the issued token.
Try it in one minute
The demo requesting application walks the full flow in a browser and shows, at the end, every step it took and the RAR entries that reached the token. Type your own email: the second factor goes to the address you enter.
Where each piece lives
| Host | Role |
|---|---|
directory.efraingaray.com | Participant Directory. Routes under /public need no certificate. |
auth.efraingaray.com | Authorization server. Browser leg of the flow. |
mtls.efraingaray.com | Same server over mTLS: PAR, token and dynamic registration. |
api.efraingaray.com | Bank resource APIs. Client certificate required. |
banco.efraingaray.com | Banco Fantasma: consent screen and second factor. |
psbi.efraingaray.com | Demo requesting application. Start here. |
Plugging in your own implementation
Four steps. The first three are done once; the fourth is the flow itself.
1 · Get your certificates
Every participant needs three: transport for mTLS, signing for PS256, and encryption for the request object. The sandbox ships a script that issues them from its own CA, which is the only CA this sandbox trusts.
git clone https://github.com/efraingaray/sfa-sandbox cd sfa-sandbox && ./pki/crear-pki.sh mi-psbi # Deja tres pares en pki/out/mi-psbi/: # transport-cert.pem transport-key.pem -> mTLS # signing-cert.pem signing-key.pem -> PS256 # encryption-cert.pem encryption-key.pem -> RSA-OAEP2 · Register in the Directory
Create a software statement with your redirect URLs, upload the signing and encryption certificates, and collect the signed assertion. That assertion is what replaces paperwork.
DIR=https://directory.efraingaray.com CERT="--cert pki/out/mi-psbi/transport-cert.pem --key pki/out/mi-psbi/transport-key.pem" # a) la declaracion de software curl -s $CERT -X POST $DIR/organisations/org-psbi-0000002/softwarestatements \ -H 'Content-Type: application/json' \ -d '{"ClientName":"Mi PSBI","RedirectUri":["https://mi-app.example/callback"]}' # b) los certificados de firma y de cifrado for USO in sig enc; do case $USO in sig) F=signing;; enc) F=encryption;; esac curl -s $CERT -X POST \ $DIR/organisations/org-psbi-0000002/softwarestatements/$SSID/certificates/$USO \ -F "publicKeyFile=@pki/out/mi-psbi/$F-cert.pem" done # c) la SSA firmada en PS256 por el Directorio curl -s $CERT \ $DIR/organisations/org-psbi-0000002/softwarestatements/$SSID/assertion3 · Register dynamically at the authorization server
Present the assertion. Before creating the client, the sandbox verifies its signature, its expiry, its jti and that your participant is still Active in the Directory.
curl -s $CERT -X POST \ https://mtls.efraingaray.com/realms/sfa/clients-registrations/openid-connect \ -H 'Content-Type: application/json' \ -d "{\"software_statement\":\"$SSA\"}" # Devuelve client_id y client_secret. Si el Directorio marco al # participante Inactivo, esta llamada falla: es el punto del Directorio.4 · Run the flow
Create the consent, fetch its authorization_details, build the request object, push it and send the customer to authorize. The requesting app in the repository is a working reference of exactly this.
API=https://api.efraingaray.com/open-finance # 1. el consentimiento nace ANTES del PAR, en AWAITING_AUTHORISATION curl -s $CERT -X POST $API/consents/v1/consents \ -H 'Content-Type: application/json' \ -d '{"permissions":["ACCOUNTS_READ","BALANCES_READ","TRANSACTIONS_READ"], "accountIds":["CL-ACC-000001"], "notificationEmail":"tu@correo.cl"}' # 2. su RAR, que va DENTRO del objeto de peticion firmado y cifrado curl -s $CERT $API/consents/v1/consents/$CID/authorization-details # 3. PAR obligatorio: el objeto entero como un solo parametro curl -s $CERT -u $CLIENT_ID:$SECRET -X POST \ https://mtls.efraingaray.com/realms/sfa/protocol/openid-connect/ext/par/request \ --data-urlencode "client_id=$CLIENT_ID" \ --data-urlencode "request=$JWE" # 4. y el cliente final va al navegador con el request_uri
The API contract
OpenAPI 3.1, describing only what the sandbox actually serves. If a route is not implemented, it is not in the document. It declares mutualTLS where a client certificate is required, which is what 3.1 added it for.
Opinions, corrections and ideas about what is missing go below. It is the same thread for both languages.
Comments
No comments yet. The first one is yours.