setEvent documentation should include information about it being only usable in the outer most chaincode
As mentioned here https://hlf.readthedocs.io/en/latest/developapps/transactioncontext.html#stub and also https://github.com/hyperledger/fabric-chaincode-go/blob/main/shim/interfaces.go
The information about it only be usable in the outer most chaincode should be added
What the docs say now
The Hyperledger Fabric “Transaction Context” documentation mentions:
getCreator() returns the raw identity (X.509 or otherwise) of the creator of transaction proposal. Hyperledger Fabric Docs
But it does not in that page warn that in chaincode-to-chaincode calls, this identity might not reflect the ultimate client.
In the fabric-chaincode-node API docs, the ChaincodeStub.getCreator() method is documented (or at least referenced) without that caveat. Hyperledger Foundation +1
In the Go shim package, ChaincodeStubInterface.GetCreator() returns ([]byte, error) (in Go shim) for the serialized identity. That is the low-level API. Go Packages
In the Go shim, chaincode can also call other chaincodes (via InvokeChaincode). There is no special API to propagate the original client’s identity across invocation boundaries (unless the chaincode itself passes identity in arguments or metadata).
In the Go code of upstream Fabric shim, GetCreator() (on the stub) is pulling from the signed proposal on that invocation. When chaincode A invokes chaincode B, the call is made by the peer (not by the original client), so the creator in that context is the peer (or some internal identity), not the original client.
Many chaincode design patterns assume that only the top-level chaincode (called directly by client) can rely on getCreator() to reflect the client’s identity; intermediate chaincodes (invoked via InvokeChaincode) must accept that the identity is “the caller chaincode/peer” unless the identity is explicitly passed along.
Thus, for state-based endorsement, which may require enforcing that only the original submitter (or in general the client’s certificate) can alter endorsement parameters, the chaincode must perform getCreator() in the outermost invocation—not in nested calls.
It is thus legitimate (and safely conservative) to document that getCreator() should only be considered accurate when used in the outermost chaincode (i.e. not inside nested chaincode-to-chaincode calls), unless special design is done to propagate identity.
Proposed Documentation Snippet
You can add a caveat section into the existing “Transaction Context / Stub APIs” docs (e.g. in the getCreator() description) saying something like:
Caveat: Only valid in outermost chaincode invocation
Important Note: The identity returned by getCreator() (or stub.getCreator()) reflects the submitter of the current chaincode invocation, which is always the entity that directly sent or invoked the chaincode. In a nested chaincode-to-chaincode call (i.e. when your chaincode invokes another chaincode via stub.invokeChaincode() or the equivalent), the getCreator() in the called chaincode will reflect the invoking chaincode/peer’s identity (or internal stub identity) — not the original client’s identity.
Therefore, if your logic (e.g. state-based endorsement parameter changes) must be constrained to the original client’s certificate, you should perform getCreator() only in the outermost chaincode (the one directly invoked by the client). If sub-chaincodes need to act on behalf of the client, you may need to explicitly pass the client identity (e.g. via arguments, transient data, or metadata) into the nested invocation.
In other words:
In the top-level chaincode invoked by the client, getCreator() gives you the client’s identity.
In deeper chaincode-to-chaincode calls, getCreator() does not necessarily represent the original client, so you must not rely on it for authorization logic tied to the client unless you propagate it manually.