{"record":{"id":"f0438d7956ccdc45","repo":"hyperledger/fabric","slug":"permission-denied-f0438d","errorCode":null,"errorMessage":"permission denied","messagePattern":"permission denied","errorType":"exception","errorClass":"msgprocessor.ErrPermissionDenied","httpStatus":null,"severity":"error","filePath":"orderer/consensus/smartbft/chain.go","lineNumber":666,"sourceCode":"\t}\n}\n\ntype chainACL struct {\n\tpolicyManager policies.Manager\n\tLogger        *flogging.FabricLogger\n}\n\n// Evaluate evaluates signed data\nfunc (c *chainACL) Evaluate(signatureSet []*protoutil.SignedData) error {\n\tpolicy, ok := c.policyManager.GetPolicy(policies.ChannelWriters)\n\tif !ok {\n\t\treturn fmt.Errorf(\"could not find policy %s\", policies.ChannelWriters)\n\t}\n\n\terr := policy.EvaluateSignedData(signatureSet)\n\tif err != nil {\n\t\tc.Logger.Debugf(\"SigFilter evaluation failed: %s, policyName: %s\", err.Error(), policies.ChannelWriters)\n\t\treturn errors.Wrap(errors.WithStack(msgprocessor.ErrPermissionDenied), err.Error())\n\t}\n\treturn nil\n}\n","sourceCodeStart":648,"sourceCodeEnd":670,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/consensus/smartbft/chain.go#L648-L670","documentation":"chainACL.Evaluate in orderer/consensus/smartbft/chain.go:666 wraps msgprocessor.ErrPermissionDenied (\"permission denied\") when the channel's ChannelWriters policy fails to evaluate the signature set of an incoming envelope. The SmartBFT orderer node rejected the message because the submitting identity is not authorized as a channel writer. The underlying policy error is logged at debug level and only the wrapped permission-denied error is returned.","triggerScenarios":"An envelope (typically a config update or normal transaction) is submitted to a SmartBFT ordering node; AccessController.Evaluate is called with the envelope's signature set; policyManager.GetPolicy(policies.ChannelWriters) succeeds but policy.EvaluateSignedData(signatureSet) returns an error (signature invalid, identity not a member, signer not satisfying Writers policy).","commonSituations":"Submitting config updates or transactions with an identity not listed in the channel Writers policy; using an org's admin cert where only writer certs satisfy the policy; signature verification failures due to cert rotation/expiry; misconfigured Writers policy (e.g. ANY Writers removed or restricted to a different org); submitting from an SDK with a signing identity that mismatches the envelope creator.","solutions":["Check orderer debug logs for 'SigFilter evaluation failed' to see the underlying policy error and which identity was rejected.","Verify the submitting identity satisfies the channel's /Channel/Writers policy (org MSP role, NODE OU, or explicit principal).","Update the channel Writers policy via a config update if the identity should be authorized, then restart submission.","Ensure the client signs with the same MSP identity set as the envelope creator (creator header matches signature certificate).","Confirm the MSP certs of the submitter are included in the channel config and not expired/revoked."],"exampleFix":"// before: client signs config update with non-writer identity\nenv, _ := protoutil.CreateSignedEnvelope(...) // signed by reader-only identity\n// after: sign with an identity satisfying /Channel/Writers\nsigner, _ := mspmgmt.GetLocalMSP().GetDefaultSigningIdentity()\nenv, _ := protoutil.CreateSignedEnvelopeWithSigningIdentity(\n    common.HeaderType_CONFIG, channelID, signer, configUpdate, 0, 0)","handlingStrategy":"try-catch","validationCode":"policy, ok := policyManager.GetPolicy(policies.ChannelWriters)\nif !ok {\n    return fmt.Errorf(\"channel has no %s policy\", policies.ChannelWriters)\n}\nif err := policy.EvaluateSignedData(signatureSet); err != nil {\n    return fmt.Errorf(\"submitter identity does not satisfy %s: %w\", policies.ChannelWriters, err)\n}","typeGuard":"func isPermissionDenied(err error) bool {\n    return errors.Is(err, msgprocessor.ErrPermissionDenied)\n}","tryCatchPattern":"if err := acl.Evaluate(signatureSet); err != nil {\n    if errors.Is(err, msgprocessor.ErrPermissionDenied) {\n        // unauthorized submitter: reject with 403-equivalent, do not retry\n        return status.Errorf(codes.PermissionDenied, \"submitter not in channel Writers policy\")\n    }\n    return err\n}","preventionTips":["Verify the client signing identity appears in the channel Writers policy before submitting config changes.","Keep Writers policy (e.g. ANY of the consenting orgs' writers) consistent across all orderers via the channel config.","Rotate and re-register identities before certificates expire; re-submit after MSP updates.","Enable orderer debug logging (SigFilter evaluation failed) in staging to catch policy mismatches early."],"tags":["hyperledger-fabric","ordering","access-control","policy"],"backgroundTag":"permission-denied-by-policy","analyzedSha":"2736b63f8fd5932511d56fe68b7039d15977f7f6","analyzedAt":"2026-09-04T08:52:36.465Z","contentChangedAt":"2026-09-04T08:52:36.465Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}