Authorization in Canton

Hello community,

I am trying to setup Authorization in my Canton network.

In Static Config , it specifies how this configuration should be set up:

_shared {
ledger-api {
auth-services = [{
  // type can be
  //   jwt-rs-256-crt
  //   jwt-es-256-crt
  //   jwt-es-512-crt
  type = jwt-rs-256-crt
  // we need a certificate file (abcd.cert)
  certificate = ${JWT_CERTIFICATE_FILE}
}]
}
}
  1. How can i create a certificate file?
  2. Is this the JWT token to place in the certificate file? Should i encode the following structure with the specified algorithm?
{
   "aud": "someParticipantId",
   "sub": "someUserId",
   "exp": 1300819380
   "scope": "daml_ledger_api"
}

Thank you,

The certificate is the X.509 certificate that must sign JWTs supplied with ledger API requests, and that the server will use to check those signatures; it is not a JWT itself. See the documentation linked from what you linked for details.

Hi @Derek ,

  1. The certificate (and the corresponding signing key) is generated externally. You can use tools such as openssl for self-signed cert generation. The signing key is then used for jwt generation (see point 2), while the certificate is configured in the ledger-api.

  2. This part you showed is the payload of the jwt, which is the user ID defined in the participant node. If you are using jwt.io (for demo and testing) you can choose the right algorithm (e.g. RS256), place the payload, and paste the signing key in the private key part (inside the “verification” box, which is a bit confused). Then the result in encoded box is the jwt to be used when accessing the ledger-api. You can also use other tools / libraries to generate the jwt with the proper algorithm, signing key and the payload.

cheers,
kc

1 Like

Hello again,

Thanks for the answer,

I generated my certificate and signing key with the following command:

openssl req -nodes -new -x509 -keyout sandbox.key -out sandbox.crt

After that, i updated my config file:
image

When i initialise the participant, i get this error:

WARN c.d.l.a.a.Authorizer - UNAUTHENTICATED(6,0): The command is missing a (valid) JWT token, context: {participant: "participant1", err-context: "{location=Authorizer.scala:256}"}

Hi Derek,

I don’t have this problem when I bring up a setup with your configuration. Are you starting using ledger-api? I saw this once when I bring up the sandbox with the dar specified to be uploaded. It turns out that uploading a DAR requires ledger-api, which causes an unauthenticated error message. See if that’s the case you are encountering.

kc

This is all my config file:

And init file:
image

I think i dont start ledger-api (how can i do this?). I restarted the setup and uploaded the dar (in domain node) to the participant and i get this error:

How can i solve this?

Thank you,

Hi Derek,

I somehow simulated the case you are encountering. I assume you successfully bring up the participant1 and domain, and the connection (your “init file”) of participant1 to domain is successful. You can check if it’s the case by participant1.health.status and you can see it’s connected to domain.

Then if you are using a canton remote console (i.e. using remote-participants), when you upload DAR it will go through the ledger-api, which requires authentication. That’s where I see this error.

I didn’t try doing this on the remote console. What I have tested is using daml sdk to perform the dar upload with the right JWT. The command looks like this.

daml ledger upload-dar <dar-file> --host <p1's ledger-api.address> --port <p1's ledger-api.port> --access-token-file participant_admin_signed_jwt

here the token file participant_admin_signed_jwt is created according to my previous reply (using jwt.io), with userid participant_admin.

See if this works in your case. I will do some test and see if I can upload DAR using canton console in parallel.

cheers,
kc

Hello kctam,

Yes, i have 2 remote participants and they are connected to domain. [IMAGE FROM PARTICIPANT1 CONSOLE]

I have tried the command you suggested in Participant1, but i think i am missing something in the jwt token.
I created a file with the JWT encoded token, and then uploaded to the ledger using your command.
I set userid like you said (participant_admin).

This is my JWT.

After that, i get no erros in participant1 and domain console.

But now i cant access navigator or json-api.

NAVIGATOR ERROR:

JSON API ERROR:


JWT used to access JSON API:

I think it has something to do with the token file because without authorization this all worked.

Thank you

Hi Derek,

I have done some quick tests.

For JSON-API, you don’t need the --pem and --crt, which are for TLS (you are not using TLS here). This command should work.

daml json-api --http-port 7575 --ledger-host localhost --ledger-port 5011 --allow-insecure-token

What you need is to provide the signed JWT in Auth Bearer Token.

For Navigator is a bit tricky. Again, the --pem and --crt are not needed. But you have to specify the --access-token-file.

daml navigator server localhost 5011 --access-token-file <signed jwt>

You may turn out need a jwt (a user id) with ParticipantAdmin rights (to get the list of users) plus the user rights (for your user selected in navigator) before using Navigator. Bear in mind that Navigator is more a development tool. See if you wish to create such a specific user which is just used in navigator.

cheers,
kc

1 Like

Hello again, i am still struglling,

For JSON API:
I now get a 400 Bad Request, but i am trying to solve it.

For NAVIGATOR:
I can lauch navigator but now i get a error in Canton console and i cannot see the contracts created before:

WARN c.d.l.a.a.Authorizer - PERMISSION_DENIED(7,0): Claims do not authorize to read data for party ‘bob::122033f10bca62fab35e0d8c3abee47abc23b78c8d91c90841ad7d4956c984eefecc’, context: {participant: “participant1”, err-context: “{location=Authorizer.scala:218}”}

You’re saying that i need a jwt token for the navigator, but I am already passing a token in the file, how can I add what you are suggesting.

The navigator for me serves only as an interface to view the contracts.

In JSON API i have this error:

My JWT token is:

{
  "https://daml.com/ledger-api": {
    "ledgerId": "participant1",
    "applicationId": "foobar",
    "actAs":["bob::1220c464ac5d2366783adcb9f9c8afd0167cfef3a198e586589552efe8c214991124"]
  }   
}

Any clue?

Thank you

I’m using user management when generating JWT (link) And here is my token payload

{
  "aud": null,
  "sub": "alice",
  "exp": 1963027803,
  "scope": "daml_ledger_api"
}

in “sub”, i use “participant_admin” for user/party management, while “alice” etc for the actual users created in the participant node.

Note that I didn’t include the party ID and Act-as in the JWT payload. It is pre-2.0, and the mapping of user → rights are managed in user management.

Regarding the Navigator: assuming you have a party Alice::namespace allocated in the participant node. If you wish the Navigator that can read the user list (for front page) and act/read as Alice::namespace, you need to create a new user (say aliceadmin) that can act/read as Alice:: and the right ParticipantAdmin. But it’s only good for testing/demo. The rights of such a user would like this (note it is not payload of JWT, but the rights defined in participant node for a given user aliceadmin and when creating a user aliceadmin in JSON-API).

{
  "userId": "aliceadmin",
  "rights": [
    {
      "type": "CanActAs",
      "party": "Alice::namespace"
    },
    {
      "type": "CanReadAs",
      "party": "Alice::namespace"
    },
    {
      "type": "ParticipantAdmin"
    }
  ]
}

You can find more about using JSON-API and user management in the dock here. Don’t forget to use JWT with user id participant_admin for user management JSON-API.

kc

1 Like

Hello kctam,

I tried your suggestion today, on the navigator subject. I created a user (bob) as you said. I set the JWT token and uploaded it to the ledger:

{
  "aud": null,
  "sub": "bob",
  "exp": 1963027803,
  "scope": "daml_ledger_api"
}

Now i can visualize my contracts, but i still get one error:

Any thoughts?

As you can see, the user bob is created with the rights you recommended:

Regarding JSON API, I was able to create a contract between 2 participants (bob with authentication and alice without authentication) and visualize it in both navigators. (the next step is to add authentication in alice).

Thank you for your help.

Hi Derek,

I suspect it may be related the use of Application ID as the User ID. See some questions I raised before (link and link). I haven’t gone in details in the Navigator in terms of the application-id part. But if you r JSON-API is working, see if it’s ok to rely on it. Or you can prepare another ask in the Forum focusing on the navigator error message.

cheers,
kc

1 Like