11°

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

HostRole
directory.efraingaray.comParticipant Directory. Routes under /public need no certificate.
auth.efraingaray.comAuthorization server. Browser leg of the flow.
mtls.efraingaray.comSame server over mTLS: PAR, token and dynamic registration.
api.efraingaray.comBank resource APIs. Client certificate required.
banco.efraingaray.comBanco Fantasma: consent screen and second factor.
psbi.efraingaray.comDemo requesting application. Start here.

Plugging in your own implementation

Four steps. The first three are done once; the fourth is the flow itself.

  1. 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-OAEP
  2. 2 · 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/assertion
  3. 3 · 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. 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.

Reviewed before publishing. The email is not stored and never appears anywhere.