- Docs
- Data Control Platform
- SDKs
- JavaScript
- React
Getting Started
IronCore is a data privacy SDK and cloud service. The getting-started-react repo is a sample React application that uses IronCore to grant, monitor and revoke access to sensitive data.
You can get a look at this example in action - we are hosting an instance of it as a demo here.
Clone, install, start
If you’d like to get a more in depth look at how the app works and how it uses IronCore’s Data Control Platform to protect data, you can download the code and run the example on your own machine.
bashgit clone https://github.com/IronCoreLabs/getting-started-react.git cd getting-started-react npm install
This sample React application can be run in two different modes to showcase how to layer in application level encryption to your app. At first we will run the application where none of the data is encrypted to get an idea for how the application functions. Then you can run the application with IronCore’s IronWeb JavaScript SDK to show how data can be end-to-end encrypted and decrypted directly within a React client application.
To start up the app in its initial state, run
bashnpm run insecure
This will automatically open up a new tab on your browser and point to the demo application running on localhost:3000
.
Our mission
Our mission is to develop an application for Captain James T. Kirk of the Starship Enterprise. When the Enterprise explores a new planet, Captain Kirk selects crewmembers to visit the planet surface. These crewmembers make up the away-team
. Kirk needs to be able to send the away-team
orders without having the commands be seen by adversaries.
As the captain of the Starship Enterprise, I want a way to securely share commands with my away team, So that Romulans and Klingons do not intercept my commands and kill us.
When you load the application for the first time, you will be logged in as Captain Kirk and an away-team
group with Captain Kirk as a member is created behind the scenes. We’ll start first by creating our first order.
Creating Our First Order
Encrypt an order with these three steps:
- Enter an order title
- Enter an order message
- Click Encrypt your order
NOTE: As mentioned above, for the purposes of this part of the demo, our first orders will not be end-to-end encrypted in our sample application.
Once a new plaintext order is added it will appear in the list of orders below the creation form. Now that we have our first order, let’s experiment with what other members of the Starship Enterprise can see. Click on the “Acting as: Kirk” in the top right of the screen to simulate logging in as another member of the Starship Enterprise. For now, none of these other users are part of the away-team
group.
Pick another user from this list to log in as them. From this users perspective they’ll see the order Kirk created and are able to see the contents of the order. Because this order wasn’t encrypted, any other user in the system can see it, whether they should be able to or not.
In the majority of todays applications restricting who has access to see what data is implemented via access control logic. In many applications this logic can be complex, brittle, and easy to introduce bugs which can lead to data breaches. Encrypting this data provides a much better layer of security.
Enabling IronCore Encryption
Now that we understand the core concepts of how our sample application works, let’s seamlessly add in the IronWeb JavaScript SDK to end-to-end encrypt our secret orders. From the terminal run:
bashnpm run secure
This will open the application again and everything will look the same, but now all the orders that are created will be end-to-end encrypted and only viewable by those we allow. While logged in as Kirk, create a new order and encrypt it. The new order will show up in the list. At this point the order content is fully encrypted and viewable only by Kirk. You can click the order title to see a decryption happen directly in the browser to reveal the encrypted content.
Unauthorized Decrypt
Now change the actively logged in user to Spock. When logged in as a different user, you’ll see that they are not able to see the encrypted order that we created.
Let’s see what happens when Captain Kirk adds Spock to the away-team
group.
Adding Users to the Away Team
- Click
Acting as: Spock
to drop down the list of crew members. - Select
Kirk
Now add Spock to the away-team
group with the following steps:
- Click the
Manage Away Team
button in the upper right header. - Click the
+
sign next to Spock. - While we are here, add Redshirt as well by clicking the
+
sign next to his avatar.
Now switch back to login as Spock. You will see that this time, Spock is able to see the decrypted order:
Fascinating.
Without touching the underlying data (order), Spock is granted access to the encrypted command. Behind the scenes, IronCore is using transform encryption. Transform encryption allows ciphertext encrypted to a group (e.g., the away team
) to be transformed into ciphertext encrypted to a group member (e.g., Spock). The group member then locally decrypts data using their private key.
Transform encryption is referred to as proxy-encryption (PRE) in the academic literature. IronCore is the first commercialization of proxy-encryption (PRE). You can read more about transform encryption in the ACM paper Cryptographically Enforced Orthogonal Access Control at Scale
Revoke access
Now to continue our voyage.
Unfortunately, Ensign Redshirt did not return from the latest away team mission. Captain Kirk has to, ahem, offboard him. Remove Redshirt from the away team with the following steps:
- Make sure you are
Acting as: Kirk
- Click on
Manage Away Team
to open the Team Management side drawer. - Remove Redshirt from the away-team.
- Switch
Acting as: Kirk
toActing as: Redshirt
.
You will see that Ensign Redshirt is unable to decrypt the command.
Again, without touching the underlying data, you are able to revoke access to it. If you have heard about the GDPR privacy right to forget, this is an effective way to implement it.
Implementation Details
Now let’s dig into the details about how this React application implements end-to-end encryption. Our React application uses the popular Redux library to handle state management. Changing from a plaintext order version to one that is fully end-to-end encrypted involves adding Redux Middleware to handle encrypting and decrypting orders as actions are triggered in our application.
We have two separate middleware methods for encrypting and decrypting content as it passes through our Redux flow.
Encryption Middleware
JavaScriptexport const encryptionMiddleware = (store) => (next) => (action) => { if (action.type === "ADD_ORDER") { return encryptNewOrder( next, action, store.getState().awayTeam.id ); } next(action); };
Our encryption middleware filters the actions to just the ADD_ORDER
action. This allows other non encryption related actions to be ignored by our middleware. When we do have an ADD_ORDER
Redux action, the following method handles it:
JavaScriptfunction encryptNewOrder(next, action, awayTeamID) { return IronWeb.document .encrypt( IronWeb.codec.utf8.toBytes(action.payload.body), {accessList: {groups: [{id: awayTeamID}]}} ) .then((encryptedDoc) => { next({ ...action, payload: { ...action.payload, body: IronWeb.codec.base64.fromBytes(encryptedDoc.document), id: encryptedDoc.documentID, encrypted: true}, }); }) .catch((e) => {...}); }
Our encryption middleware takes the ADD_ORDER
action and encrypts the action’s payload.body
while at the same time granting access to the document to our away-team
. Upon success, it replaces the actions payload with the resulting encrypted content and augments the data to denote that it has been encrypted. This action is then passed along in its normal Redux flow which, for most applications, ends up making a request to the backend service to store the data.
Decryption Middleware
JavaScriptexport const decryptionMiddleware = (state) => (next) => (action) => { if (action.type === "GET_ORDER") { //When we get an action for a new order we need to conditionally //decrypt it if the data is encrypted. If this order was created //prior to encryption, we just want to pass it along. Otherwise //we want to decrypt it and pass along an action with the decrypted data. if (action.payload.encrypted) { //Data is encrypted, decrypt, and then modify the action content //with the decrypted content before dispatching return decryptOrder(next, action); } return next(action); } next(action); };
Our decryption middleware is similar to encryption where it will first filter the actions that it cares about to only the GET_ORDER
action. This also has a check to make sure the data is encrypted before attempting to decrypt the data. When we get an encrypted GET_ORDER
Redux action, the following method handles it:
JavaScriptfunction decryptOrder(next, action) { IronWeb.document .decrypt( action.payload.id, IronWeb.codec.base64.toBytes(action.payload.body) ) .then((decryptedDoc) => { next({ ...action, payload: { ...action.payload, body: IronWeb.codec.utf8.fromBytes(decryptedDoc.data)}, }); }) .catch((e) => {...}); }
Upon decrypt, we use the IronWeb SDK to decrypt the action’s payload.body
at which point we replace that data with our decrypted content before sending it along to the next step in the Redux action flow.
By implementing this encryption/decryption workflow with a Redux middleware we were able to seamlessly add end-to-end encryption to our application without having to re-architect any major parts. This can be seen by the fact that the only difference between running npm run insecure
and npm run secure
is whether this Redux middleware is applied to our application or not.
The Final Frontier
That completes your first mission. By adding a new Redux middleware you’ve built an application that has better privacy and security than most web applications on Earth.
Now it’s time to explore integrating IronCore into your application. To do so, sign up for your account at https://admin.ironcorelabs.com/.
Live long and prosper.