cinnamon-rolling
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Engagement control
    • Make a copy
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Make a copy Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    <center> <img src="https://i.imgur.com/OBiQN9X.png" /> </center> === <center> <h1> <a href="https://youtu.be/NAAIVyq9gcU">Video Demo</a> </h1> </center> <center> <h5> <a href="https://github.com/xmliszt/e-safe">Project GitHub Link</a> </h5> </center> <center> <hr> <div>Yuxuan 1003607</div> <div>Jia Yi 1003696</div> <div>Johnson 1003651</div> <div>Dev 1003375</div> <div>Zewen 1003623</div> </center> **Team** --- [TOC] --- # Introduction and Problem Formulation Our group aims to design and implement a Distributed Storage Solution that allows for Identity and Access Management (IAM) and secure storage of Secrets while distributing security liability. We aim to mimic DynamoDB's storage system in order to create this secret storage system. # Overall System Architecture ![](https://i.imgur.com/o3of8um.jpg) E-Safe distributed system design is as shown above. Nodes are arranged in a ring structure around the Locksmith server. All nodes are communicating with one another via Remote Procedure Call (RPC). Each node has a unique RPC address to constantly listen to internal RPC requests from other nodes. The Locksmith server is responsible for periodically checking the heartbeat (i.e. whether the node is alive) of each node available, monitoring the coordinator status. If the current coordinator node is down, the Locksmith server will assign coordinator to the next alive node with the highest node ID. The Coordinator node is responsible for activating the router within to listen for incoming clients' requests from the end-users. The Controller layer will validate the requests and handle them by calling the service layer. Service layer will then call the Repository layer to make changes or retrieve information from the local file storage. The Service layer will also send RPC calls to other nodes in times of data replication and re-distribution. Each node's start-up process will include sending RPC requests to the Locksmith to get the latest copy of the shared resources (namely the Heartbeat Table, the RPC addresses, as well as the Virtual Node Structure) and broadcast to every other node. This is to ensure that the shared resources in each node are consistent throughout the system. # Design ## Terminology - **Locksmith server**: The central server that checks aliveness of other nodes and controls coordinator assignment. - **Coordinator**: The special node appointed to listen to clients' requests from Front-end. It is also responsible for hashing the request and computing the replication locations. - **Node**: A single node that performs main functionality of the system, such as getting secrets, creating secrets, updating secrets, login users, registering users. Each node has a router component but only the coordinator node will activate the router. Each node is identified by its unique ID, starting from 1. - **Heartbeat table**: The table that shows the aliveness of each node. - **RPC addresses map**: A mapping of node ID to its respective RPC listener address. Every node's address has the host of `localhost` and the port of `5000 + nodeID`. Locksmith's address is `localhost:5000`. Node ID minimum is 1. - **Shared Resources**: The shared resources refer to any local data in each node that is suppoded to be consistent in the system. Though they are local, they appear to be *shared* as every node has the excat same values for these data. - **Owner Node**: The node to which the original data is stored. Owner node is responsible for relaying the replications to the subsequent nodes to store the replicas. - **Replica Node**: The node to which the replica of the original data is stored. ## Features ### User Features - **Register user**: User is able to register for new user account, username must be unqiue. ![](https://i.imgur.com/mWqOUME.png) - **Login user**: User is able to login using his/her username and password. ![](https://i.imgur.com/iH4BENd.png) - **Create a secret**: User is able to create a new secret - keying in the alias/description of the secret and the value of the secret. ![](https://i.imgur.com/Elxruje.png) - **View accessible secrets under the role**: User is able to view all the secrets that are accessible by him/her, based on his/her role. Role ranges from 1 to 5, with `role=1` being the role with highest accessibility (i.e. super admin) ![](https://i.imgur.com/gCn8blb.png) - **Edit a secret**: User is able to edit a secret to a new value ![](https://i.imgur.com/pROglkw.png) - **Delete a secret**: User is able to delete a existing secret ![](https://i.imgur.com/r9wOsL4.png) - **Monitor node status**: ***(Demo)*** User is able to monitor the nodes status. Tables showing all virtual nodes and physical nodes status and locations, together with a Doughnut chart will be shown in the monitoring dashboard. ![](https://i.imgur.com/F59kVUm.png) ### Technical Features - **Fault Detection**: The Locksmith server is able to detect node failure via heartbeat checking and immediately modify shared resources, updating all alive nodes about the changes, and assigning a new coordinator if the dead node happens to be a coordinator. - **Consistent Hashing**: Each virtual node's name and all incoming data's keys are hashed using the same hashing function. With the ring structure, it makes data re-distribution during system scaling have a smaller overhead. - **Virtual Nodes**: Each node has a number of virtual locations in the ring structure to achieve *load balancing*. - **Fault Tolerance**: When a node is down, the request from the client will still be served continuously without the need for retrying, thanks to our data replication. - **Node Recovery**: A dead node with lost data is able to revive and recover the lost data from other nodes. The Locksmith server is able to handle the recovery and update all shared resources accordingly. - **Scalability**: Our system is able to scale up and down easily by adding or removing the node, without the worries of lost data or missed clients' requests. ## Assumptions - **No Byzantine node**: Our group has opted to not implement interventions for malicious, or bayzentine, nodes. - **Non-volatile storage**: Although Dynamo DB, our reference architecture, tends to implement storage of data onto non-volatile storage that allows them to spin up a new node and ensure data persistency through crashes without the need to search for replicas during recovery - we have opted not to do this. This is partly due to the fact that even with non-volatile storage, a reassurance check should still take place to verify data persistance and correctness. Therefore, with the assumption that a node dying looses all its data, we were able to implement an algorithm that not only recovers the data on node recovery but also redistributes the data as the node position is rehashed on recovery. - **Locksmith server is fault-proof**: Our locksmith server helps update the heartbeat table and we have assumed that it is fault-proof and therefore cannot die. ## Consistency Due to the lack of concurrent operations that need to be handled by the system, we do not requeire a specific protocol to handle consistency. Our system does however guarantee that whatever the client has read/written will be reflected in the database at all times. This is because the router that handles receiving the requests makes sure to queue all requests. This means that there is some form of total order at all times. We also guarantee data consistency because of our replication algorithm. As long the number of nodes down is leser than or equal to the replication factor, there will always be a replica of the data always available for the client to access. ## Scalability ### Load Balancing Our group implements consistent hashing to create **virtual nodes**. Each physical node is hashed into multiple virtual nodes (can be set in the `config.yaml` file). The concept of virtual node is similar to that of DynamoDB, where it helps with load distribution. An example of a physical node ring structure and how it looks like after implementing the concept of virtual nodes can be seen as follows: ![](https://i.imgur.com/DpMSP6W.png) Virtual nodes allows for data to be redistributed more evenly across all available nodes. As seen from the diagram above, when only physical nodes are implemented, there might be a higher chance where the data is stored in the same node, which makes the burden on a node high. However, with the the implementation of virtual nodes, it spreads out the structure of nodes, where each physical node is responsible for a more random range of data to be stored. ### Addition and Deletion nodes We implement the concept of **consistent hashing**, where each virtual node is hashed into each individual location based on a unique hash function, where it hashes the virtual node ring string three times to create more randomness, and output a unique 32-bit integer. Due to the uniqueness of hashing, every unique input will result into the a unique output, therefore, no overlapped locations will be created. When a new node is spawned, with virtual nodes created, it will be inserted into the virtual node ring structure after passing through our unique hash function. It will then grab its secrets from its neighbours and store it in itself. As the data is stored in a clockwise manner, it will get its data from the subsequent node, claiming itself as the owner node of the data. On top of that, it will query the previous nodes's replicated data to store in itself as well. ![](https://i.imgur.com/KRWTZF4.png) When a node crashes, we assume that the data is wiped out. The node structure will change accordingly as well. ## Fault Tolerance ### Failure Detection - Heartbeat Table - The locksmith server will ping each member of the ring structure to check for liveness. In the scenario a node has been found to be dead (heartbeat == false), the locksmith server will trigger a recovery action based on the node that has died. If it was a Coordinator, the locksmith server will assign the next highest ID node as the Coordinator and the handover process will ensue. In all cases, data redistribution between the remaining nodes will take place. When the node recovers, the Node ID will be hashed again as it is inserted into the ring and data is redistributed again. ### Replication strategy Given a repliation factor ```n```, our system ensures that we have `n` replicas in the system at all times. A pictorial representation of the replication strategy can be seen below. ![](https://i.imgur.com/f8t1slX.png) Our replication strategy occurs in 2 phases. The first phase is shown in the picture by the green and blue arrows numbered 1 to 4. When the coordinator receives a request to write data into the system, it first finds the owner virtual node that is responsible for the data. In this case, this will be node 1-3. The coordinator then sends the data to the owner node, along with a list of all the nodes that can store the replica of the data being sent, shown by arrow 1 in the picture. This list is generated according to two conditions. The replica virtual node must be a succeeding virtual node from the owner virtual node in a clockwise manner, and the physical node of the replica node must not already exist in the list. For example, in the picture above, we skip node 5-1 since we are already storing the replica in the physical node 5 via vitual node 5-3. Once the owner virtual node receives and stores the data from the coordinator, it sends the data to the first node in the generated list. It then requires this subsequent node to store the replica data and send an acknowledge message back to the owner virtual node. This ensures that at least replica is guaranteed to be stored in system at all times. This is shown by arrow 2 and 3 in the picture. Once the owner virtual node receives the acknowledge message from the first node in the list, it sends an acknowledgement message back to the coordinator to conclude the operation. This is shown by arrow 4. The second phase of the strategy starts here. The virtual node with the replica will then itself look at the next virtual node in the list and send the data over to it for storage. This subsequent node will do the same until all the nodes in the generated list have been traversed. This is shown by arrows 5 and 6 in the picture. We decided not to implement acknowledgement messages for all `n` replicas to trade-off between the time the client has to wait to receive an acknowledgement of a successful write to the system and the guaranteed creation of the replica of data. ### Tolerance to dead node - Supports up to (Replication Factor) nodes dead. - To make sure the system has at least one replica of data, our system allows a maximum of the replication factor (3) number of nodes to die. Under this condition, for the worst case, the next two nodes of the owner node die. The list of the next three nodes which were generated by the coordinator will only contain only one node location, and the owner node will only send strict consistency with the replication factor of 1 to that location. After the third node store the replica in its storage, it will send acknowledge message to the coordinator. Under this condition, at least one replica is stored and can be found when required. - When node down, replication continues as per normal - When the number of dead nodes is smaller than the replication factor, the coordinator will generate a list of node locations that contain the replication factor (3) less the number of the dead nodes number ```(RF - No. of dead nodes)``` of nodes. This will then be sent to the owner node which will start the replication process based on the list received. An example of one physical being down is shown in the picture below ![](https://i.imgur.com/uDoGpfA.png) - Service is not affected when a node is down - Since the system guarantees that there is at least one additional replica stored in some neighboring node. Under this condition, even if the owner node is dead, the system will still be able to get the replica of the information form the neighboring node before sending it to the client. ### Recovery There isn't a distinct recovery algorithm that was implemented for our system. This is because the recovery algorithm is akin to adding a new node to the system. When a node dies, it is removed from the ring structure and the heartbeat table is updated to reflect that it has died. If it wakes up again, the Locksmith treats this node as a new node that is being added to the ring structure, and runs the 'add-node' algorithm to add the revived node back into the ring structure. In the event the coordinator node dies, our election algorithm reassigns the coordinator responsibilities and status to the next node that has the highest PID. When the previous coordinator node reawakens, the election algorithm is run again and the revived node is given back the status and responsibilities as coordinator. ## Limitations - Fixed storage overall - While we were able to add more nodes into our distributed storage solution, this only helped us in balancing load of incoming messages. The overall capacity for key-value pairs that we were able to store was limited by our Hash Function at ```2^32```. While this is a large number, it is still a hard limit on our entire system as trying to store the ```2^32 + 1```th key-value pair will definitely result in a clash. - Number of nodes must be greater than the Replication Factor - The number of nodes that our distributed system requires to be operating effectively in the said manner described above requires it to have more physical nodes than the number of the Replication Factor ```(No. of Physical Nodes > RF)``` - No auto-scaling - We have not implemented a system that is able to automatically guage the load of each individual node and trigger a scale-up, or scale-down, event. This currently takes place manually when we introduce a new node to the distributed store or kill a node manually. # Conclusion Through project e-safe, we have been able to implement a distributed storage solution for secrets with Identity and Access Management (IAM). This allows teams and enterprises to ensure IAM is maintained while their secrets are stored in a distributed system that allows for a reduced security liability. We have made this system reliable (ensuring correctness), fault-tolerant and aware (fault-detection). This system's original inspiration was Dynamo DB and some of the protocols and design principles seen here are a direct influence of Dynamo's design. With e-safe, we believe we have been able to create a secure and reliable storage for enterprises and teams to store their e-secrets. # Appendix **Base URL** `http://localhost:8081` | Name | Endpoint | Method | Available Status | | -------- | -------- | -------- | ---------- | | Login | `/login` | POST | 200, 401, 404, 500| | Register | `/register`| POST | 200, 400, 409, 500 | | Get a secret | `/api/v1/secret?alias={}` | GET | 200, 400, 401, 500 | | Create/Update a secret | `/api/v1/secret` | PUT | 200, 400, 401, 500 | | Delete a secret | `/api/v1/secret?alias={}` | DELETE | 200, 400, 401, 500 | | Get all secrets | `/api/v1/secrets` | GET | 200, 400, 401, 500 |

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully