Skip to content

Commit ce52828

Browse files
author
Jason Yellick
committed
[FAB-2670] Document fabric policies creation/usage
https://jira.hyperledger.org/browse/FAB-2670 This is a small markdown document intended to be a starting point to understanding the policy structure of the fabric. It is targetted for developers who would like to roll their own configuration for a channel. Change-Id: Ic96798e51e4e1f20ddf9c5bb7da30d6630c3bc0d Signed-off-by: Jason Yellick <[email protected]>
1 parent 9cbf5e6 commit ce52828

File tree

1 file changed

+271
-0
lines changed

1 file changed

+271
-0
lines changed

docs/policies.md

+271
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,271 @@
1+
# Policies in Hyperledger Fabric
2+
3+
Configuration for a Hyperledger Fabric blockchain network is managed by policies. These policies generally reside in the channel configuration. The primary purpose of this document is to explain how policies are defined in and interact with the channel configuration. However, policies may also be specified in some other places, such as chaincodes, so this information may be of interest outside the scope of channel configuration.
4+
5+
## What is a Policy?
6+
7+
At its most basic level, a policy is a function which accepts as input a set of signed data and evaluates successfully, or returns an error because some aspect of the signed data did not satisfy the policy.
8+
9+
More concretely, policies test whether the signer or signers of some data meet some condition required for those signatures to be considered 'valid'. This is useful for determining that the correct parties have agreed to a transaction, or change.
10+
11+
For example a policy may define any of the following:
12+
* Administrators from 2 out 5 possible different organizations must sign.
13+
* Any member from any organization must sign.
14+
* Two specific certificates must both sign.
15+
16+
Of course these are only examples, and other more powerful rules can be constructed.
17+
18+
## Policy Types
19+
20+
There are presently two different types of policies implemented in the hyperledger fabric.
21+
22+
1. **SignaturePolicy**: This policy type is the most powerful, and specifies the policy as a combination of evaluation rules for MSP Principals. It supports arbitrary combinations of *AND*, *OR*, and *NOutOf*, allowing the construction of extremely powerful rules like: "An admin of org A and 2 other admins, or 11 of 20 org admins".
23+
2. **ImplicitMetaPolicy**: Tihs policy type is less flexible than SignaturePolicy, and is only valid in the context of configuration. It aggregates the result of evaluating policies deeper in the configuration hierarchy, which are ultimately defined by SignaturePolicies. It supports good default rules like "A majority of the organization admin policies".
24+
25+
Policies are encoded in a `common.Policy` message as defined in `fabric/protos/common/policies.proto`. They are defined by the following message:
26+
27+
```
28+
message Policy {
29+
enum PolicyType {
30+
UNKNOWN = 0; // Reserved to check for proper initialization
31+
SIGNATURE = 1;
32+
MSP = 2;
33+
IMPLICIT_META = 3;
34+
}
35+
int32 type = 1; // For outside implementors, consider the first 1000 types reserved, otherwise one of PolicyType
36+
bytes policy = 2;
37+
}
38+
```
39+
40+
To encode the policy, simply pick the policy type of either `SIGNATURE` or `IMPLICIT_META`, set it to the `type` field, and marshal the corresponding policy implementation proto to `policy`.
41+
42+
## Configuration and Policies
43+
44+
The channel configuration is expressed as a hierarchy of configuration groups, each of which has a set of values and policies associated with them. For a validly configured application channel with two application organizations and one ordering organization, the configuration looks minimally as follows:
45+
46+
```
47+
Channel:
48+
Policies:
49+
Readers
50+
Writers
51+
Admins
52+
Groups:
53+
Orderer:
54+
Policies:
55+
Readers
56+
Writers
57+
Admins
58+
Groups:
59+
OrdereringOrganization1:
60+
Policies:
61+
Readers
62+
Writers
63+
Admins
64+
Application:
65+
Policies:
66+
Readers
67+
-----------> Writers
68+
Admins
69+
Groups:
70+
ApplicationOrganization1:
71+
Policies:
72+
Readers
73+
Writers
74+
Admins
75+
ApplicationOrganization2:
76+
Policies:
77+
Readers
78+
Writers
79+
Admins
80+
```
81+
82+
Consider the Writers policy referred to with the `------->` mark in the above example. This policy may be referred to by the shorthand notation `/Channel/Application/Writers`. Note that the elements resembling directory components are group names, whlie the last component resembling a file basename is the policy name.
83+
84+
Different components of the system will refer to these policy names. For instance, to call `Deliver` on the orderer, the signature on the request must satisfy the `/Channel/Readers` policy. However, to gossip a block to a peer will require that the `/Channel/Application/Readers` policy be satisfied.
85+
86+
By setting these different policies, the system can be configured with rich access controls.
87+
88+
## Constructing a SignaturePolicy
89+
90+
As with all policies, the SignaturePolicy is expressed as protobuf.
91+
92+
```
93+
message SignaturePolicyEnvelope {
94+
int32 version = 1;
95+
SignaturePolicy policy = 2;
96+
repeated MSPPrincipal identities = 3;
97+
}
98+
99+
message SignaturePolicy {
100+
message NOutOf {
101+
int32 N = 1;
102+
repeated SignaturePolicy policies = 2;
103+
}
104+
oneof Type {
105+
int32 signed_by = 1;
106+
NOutOf n_out_of = 2;
107+
}
108+
}
109+
```
110+
111+
The outer `SignaturePolicyEnvelope` defines a version (currently only `0` is supported), a set of identities expressed as `MSPPrincipal`s , and a `policy` which defines the policy rule, referencing the `identities` by index. For more details on how to specify MSP Principals, see the MSP Principals section.
112+
113+
The `SignaturePolicy` is a recursive data structure which either represents a single signature requirement from a specific `MSPPrincipal`, or a collection of `SignaturePolicy`s, requiring that `N` of them are satisfied.
114+
115+
For example:
116+
117+
```
118+
SignaturePolicyEnvelope{
119+
version: 0,
120+
policy: SignaturePolicy{
121+
n_out_of: NOutOf{
122+
N: 2,
123+
policies: [
124+
SignaturePolicy{ signed_by: 0 },
125+
SignaturePolicy{ signed_by: 1 },
126+
],
127+
},
128+
},
129+
identities: [mspP1, mspP2],
130+
}
131+
```
132+
133+
This defines a signature policy over MSP Prinicipals `mspP1` and `mspP2`. It requires both that there is a signature satisfying `mspP1` and a signature satisfying `mspP2`.
134+
135+
As another more complex example:
136+
137+
```
138+
SignaturePolicyEnvelope{
139+
version: 0,
140+
policy: SignaturePolicy{
141+
n_out_of: NOutOf{
142+
N: 2,
143+
policies: [
144+
SignaturePolicy{ signed_by: 0 },
145+
SignaturePolicy{
146+
n_out_of: NOutOf{
147+
N: 1,
148+
policies: [
149+
SignaturePolicy{ signed_by: 1 },
150+
SignaturePolicy{ signed_by: 2 },
151+
],
152+
},
153+
},
154+
],
155+
},
156+
},
157+
identities: [mspP1, mspP2, mspP3],
158+
}
159+
```
160+
161+
This defines a signature policy over MSP Principals `mspP1`, `mspP2`, and `mspP3`. It requires one signature which satisfies `mspP0`, and another signature which either satisfies `mspP2` or `mspP3`.
162+
163+
Hopefully it is clear that complicated and relatively arbitrary logic may be expressed using the SignaturePolicy policy type. For code which constructs signature policies, consult `fabric/common/cauthdsl/cauthdsl_builder.go`.
164+
165+
## MSP Principals
166+
167+
The MSP Principal is a generalized notion of cryptographic identity. Although the MSP framework is designed to work with types of cryptography other than X.509, for the purposes of this document, the discussion will assume that the underlying MSP implementation is the fabric MSP type, based on X.509 cryptography.
168+
169+
An MSP Principal is defined in `fabric/protos/msp_principal.proto` as follows:
170+
171+
```
172+
message MSPPrincipal {
173+
174+
enum Classification {
175+
ROLE = 0;
176+
ORGANIZATION_UNIT = 1;
177+
IDENTITY = 2;
178+
}
179+
180+
Classification principal_classification = 1;
181+
182+
bytes principal = 2;
183+
}
184+
```
185+
186+
The `principal_classification` must be set to either `ROLE` or `IDENTITY`. The `ORGANIZATIONAL_UNIT` is at the time of this writing not implemented.
187+
188+
In the case of `IDENTITY` the `principal` field is set to the bytes of a certificate literal.
189+
190+
However, more commonly the `ROLE` type is used, as it allows the principal to match many different certs issued by the MSP's certificate authority.
191+
192+
In the case of `ROLE`, the `principal` is a marshaled `MSPRole` message defined as follows:
193+
194+
```
195+
message MSPRole {
196+
string msp_identifier = 1;
197+
198+
enum MSPRoleType {
199+
MEMBER = 0; // Represents an MSP Member
200+
ADMIN = 1; // Represents an MSP Admin
201+
}
202+
203+
MSPRoleType Role = 2;
204+
}
205+
```
206+
207+
The `msp_identifier` is set to the ID of the MSP (as defined by the MSPConfig proto in the channel configuration for an org) which will evaluate the signature, and the `Role` is set to either `MEMBER` or `ADMIN`. The `MEMBER` role will match any certificate issued by the MSP, while the `ADMIN` role will match only certificates which are enumerated as admin certificates in the MSP definition.
208+
209+
210+
## Constructing an ImplicitMetaPolicy
211+
212+
The `ImplicitMetaPolicy` is only validly defined in the context of channel configuration. It is `Implicit` because it is constructed implicitly based on the current configuration, and it is `Meta` because its evaluation is not against MSP principals, but rather against other policies. It is defined in `fabric/protos/common/policies.proto` as follows:
213+
214+
```
215+
message ImplicitMetaPolicy {
216+
enum Rule {
217+
ANY = 0; // Requires any of the sub-policies be satisfied, if no sub-policies exist, always returns true
218+
ALL = 1; // Requires all of the sub-policies be satisfied
219+
MAJORITY = 2; // Requires a strict majority (greater than half) of the sub-policies be satisfied
220+
}
221+
string sub_policy = 1;
222+
Rule rule = 2;
223+
}
224+
```
225+
226+
For example, consider a policy defined at `/Channel/Readers` as
227+
228+
```
229+
ImplicitMetaPolicy{
230+
rule: ANY,
231+
sub_policy: "foo",
232+
}
233+
```
234+
235+
This policy will implicity select the sub-groups of `/Channel`, in this case, `Application` and `Orderer`, and retrieve the policy of name `foo`, to give the policies `/Channel/Application/foo` and `/Channel/Orderer/foo`. Then, when the policy is evaluated, it will check to see if `ANY` of those two policies evaluate without error. Had the rule been `ALL` it would require both.
236+
237+
Consider another policy defined at `/Channel/Application/Writers` where there are 3 application orgs defined, `OrgA`, `OrgB`, and `OrgC`.
238+
239+
```
240+
ImplicitMetaPolicy{
241+
rule: MAJORITY,
242+
sub_policy: "bar",
243+
}
244+
```
245+
246+
In this case, the policies collected would be `/Channel/Application/OrgA/bar`, `/Channel/Application/OrgB/bar`, and `/Channel/Application/OrgC/bar`. Because the rule requires a `MAJORITY`, this policy will require that 2 of the three organization's `bar` policies are satisfied.
247+
248+
## Policy Defaults
249+
250+
The `configtxgen` tool creates default policies as follows:
251+
252+
```
253+
/Channel/Readers : ImplicitMetaPolicy for ANY of /Channel/*/Readers
254+
/Channel/Writers : ImplicitMetaPolicy for ANY of /Channel/*/Writers
255+
/Channel/Admins : ImplicitMetaPolicy for MAJORITY of /Channel/*/Admins
256+
257+
/Channel/Application/Readers : ImplicitMetaPolicy for ANY of /Channel/Application/*/Readers
258+
/Channel/Application/Writers : ImplicitMetaPolicy for ANY of /Channel/Application/*/Writers
259+
/Channel/Application/Admins : ImplicitMetaPolicy for MAJORITY of /Channel/Application/*/Admins
260+
261+
/Channel/Orderer/Readers : ImplicitMetaPolicy for ANY of /Channel/Orderer/*/Readers
262+
/Channel/Orderer/Writers : ImplicitMetaPolicy for ANY of /Channel/Orderer/*/Writers
263+
/Channel/Orderer/Admins : ImplicitMetaPolicy for MAJORITY of /Channel/Orderer/*/Admins
264+
265+
# Here * represents either Orderer, or Application, and this is repeated for each org
266+
/Channel/*/Org/Readers : SignaturePolicy for 1 of MSP Principal Org Member
267+
/Channel/*/Org/Writers : SignaturePolicy for 1 of MSP Principal Org Member
268+
/Channel/*/Org/Admins : SignaturePolicy for 1 of MSP Principal Org Admin
269+
```
270+
271+
Note that policies higher in the hierarchy are all defined as `ImplicitMetaPolicy`s while leaf nodes necessarily are defined as `SignaturePolicy`s. This set of defaults works nicely because the `ImplicitMetaPolicies` do not need to be redefined as the number of organizations change, and the individual organizations may pick their own rules and thresholds for what is means to be a a Reader, Writer, and Admin.

0 commit comments

Comments
 (0)