"PERMISSION_DENIED" Error on "daml script" local canton using shared secret strategy


Recently i enhanced a canton startup shell script by starting the sandbox with a shared secret (written in auth.conf file)

canton.participants.sandbox.ledger-api.auth-services = [{
    type = unsafe-jwt-hmac-256
    secret = "XXXXX"

The script starts the canton using the auth.conf and the Navigator and Json-Api processes by using the
–access-token-file token.txt flag.

token.txt holds a JWT token that was just generated at the script starts using the same secret written in auth.conf (XXXXX above).

The canton seems to parse the auth.conf correctly and declare its unsecure mode (with a justified production usage warning):

INFO  c.d.c.CantonCommunityApp$ - Starting Canton version 2.2.0
WARN  c.d.j.HMAC256Verifier$ - HMAC256 JWT Validator is NOT recommended for production environments, please use RSA256!!!
DEBUG c.d.c.e.CommunityEnvironment - local:admin-api=6868,public-api=6867;sandbox:admin-api=6866,ledger-api=6865

After the above 3 processes are up and running we continue to a bunch of upload dars command which finishes successfully (note the usage of the same token.txt as mention before in the Navigator and Json-Api)

daml ledger upload-dar --host localhost --port 6865 --access-token-file token.txt abc.dar

daml trigger-service also seems to pass successfully but the one command after it (daml script) fails with PERMISSION_DENIED error (note the reference to the Carrier party)

Exception in thread "main" com.daml.lf.engine.script.ScriptF$FailedCmd: Command submit failed: PERMISSION_DENIED: An error occurred. Please contact the operator and inquire about the request <no-correlation-id>
Daml stacktrace:
submit at 00613824babe967d2e2df06006622a0cdb541f11615d92a07ff451f45f6c8ef6:Init.Carrier:78

Inside the sandbox.log i saw this warning regarding the Carrier party:

WARN  c.d.l.a.a.Authorizer - PERMISSION_DENIED(7,0): Claims do not authorize to act as party 'carrier::12208746707e55a23b953da341c2582c3835c9
6410a3a86fc97987df35e1c85ea3b6', context: {participant: "sandbox", err-context: "{location=Authorizer.scala:218}"}

My question is: Given the below generated JWT token payload - should i configure the readAs or actAs (or both) lists containing the “Carrier” party?

If yes, should i pass the party name or its partyId (as i believe the later is practiced in canton)?

This is the current payload for the shared secret based JWT token:

   "https://daml.com/ledger-api": {
     "ledgerId": "sandbox",
	 "applicationId": null,
	 "iss": "Example",

Hi Roni

You are on the right track. What is missing is indeed the actAs clause (just that will suffice as it implicitly contains the readAs privileges). You should use the party id i.e. carrier::12208746707e55a23b953da341c2582c3835c9.

Once you get that to work, I would also encourage you to drop the usage of the custom access token format in favor of user access tokens. In order for that to work you will have to define a user and then map it to parties in the User Management API.

I hope it helps.