Store, Recover, and Share Secrets
Now that we have initialized our orbis nodes, defined our manifest, created the secret ring, and uploaded our policy we are finally ready to store secrets into our Ring!
Store Secrets
To store a secret in a ring, theres a series of steps that clients must execute (thankfully our CLI Client does this all for you). The TLDR is that secrets must be
- Encrypted to the Secret Rings DKG Public Key
- Proof-of-Encryption commitment that cryptographically proves the first step is done correctly
- Client sends the encrypted secret and commitment proof, along with the authorization policy details to any of the Orbis nodes within the Secret Ring as a
store-secret
request. - Finally the nodes broadcast the
store-secret
request amungst eachother.
To create and store a secret, we have two methods for how the client will create the authorization policy information for the store-secret
request. These methods are called Managed
and Unmanaged
.
With Managed
authorization, the client will automatically register the required zanzibar resource to the policy when storing the secret.
The Unmanaged
authorization has no automated registration functionality, so the caller is responsible for A) Ensuring the correct resources are registed in the policy B) They correctly create the Zanzibar authorization permission string, and ensure themselves have permission to access the supplied resource.
Managed Example
To create a managed
secret with policy defined in the previous step:
orbisd client --ring-id <ring-id> put "MySuperSecretInformation" --authz managed --policy <policy-id> --resource secret --permission read
Here the client will get the <ring-id>
aggregate public key, encrypt MySuperSecretInformation
to the public key, create the proof, locally generate the <secret-id>
(determinstic), register the <secret-id>
as a new object in the <policy-id>
policy with ourselves set as the owner
, craft the full permission object <policy-id>/secret:<secret-id>#read
, and send the full store-secret
request with all this information to the Secret Ring.
Unmanaged Example
To create an unmanaged
secret, first we manually register an object into the policy, then create the secret.
# Register an object called `MySecretName`
orbisd client policy register <policy-id> secret <MySecretName>
# Create the secret using the `MySecretName` authorization object
orbisd client put "MySuperSecretInformation" --authz unmanaged --permission "<policy-id>/secret:<MySecretName>#read"
You may have noticed the difference when executing the unmanaged
request compared to the managed
request is that we can manually define <MySecretName>
instead of using the deterministically generated <secret-id>
. This is because we seperated the register
command from the put
command. Moreover, we supplied the --permission
as the fully
qualified zanizbar tuple <policy-id>/secret:<MySecretName>#read
as a single string.
In both examples, the finally request sent to the Secret Ring is similar, the encrypted secret is verified against the proof commitment, and finally broadcast to the network bulletin so it can be recieved by all the other nodes.
Recover Secrets
Now that we have stored a secret, we can send a recover
request which will trigger a Threshold Proxy Re-Encryption request. This request will first be authenticated to ensure the client requesting has the correct Proof-of-Possession JWS token, then authorized by each node before re-encryption. The authorization runs a Check
call against the Zanzi
authorization service to determine if client has the correct permission as configured when the secret was first created.
In the above example, this means the Check
call will determine if the client has the read
permission on the provided secret resource within the <policy-id>
policy.
orbisd client get <secret-id>
Note: You will need to replace
<secret-id>
with<MySecretName>
if you used theunmanaged
authorization.
This will automatically craft the proof-of-possession JWS token, intiate the proxy re-encryption request, wait for and finally decrypt the response.
Share a Secret
To share a secret with another person, we can update the policy state so that our target subject has the necessary permissions to access the secret. From our example policy before our secret
resource has an additional collaborator
relation. Moreover, the read
permission is the expression owner + collaborator
which means either the owner
or the collaborator
can read
.
We're going to add Bob
identified by did:key:z6Mkmyi3eCUYJ6w2fbgpnf77STLcnMf6tuJ56RQmrFjce6XS
as a collaborator
so he can inheir the read
permission and therefore access our stored secret.
Reminder, there is nothing specific about the names/labels used within our policy. Although we use the read
permission, there is no special power or requirement to name your permission read
, it can be any valid name.
orbisd keys add bob
export BOB=$(orbisd keys show bob --did)
orbisd client policy set <policy-id> secret <secret-id> collaborator $BOB
We can confirm that the policy relation was created by manually running a Check
command.
orbisd client policy check <policy-id> secret:<secret-id>#read
Which should return valid: true
.
Finally Bob
can also recover the secret
orbisd client --from bob get <secret-id>