Data Portability + Encryption


Hoping to get some thoughts on this because I’m happy to build something to support this concept…if it’s possible.

Today, if application data is being encrypted, it is being encrypted with a public key derived from a private key that is app-specific. And when we say app-specific, that means app origin specific. For example, if Graphite is running on and then switches to, that’s two different app origin which would result in two different keys.

That’s all fine in my book. BUT, the problem comes when we talk about giving users full ownership of their data. I want to do this in Graphite, but as far as I can tell, it’s a promise I can’t make. The user is storing their data in a storage provider of their choice (let’s assume this is enabled and someone is using Box as a simple example). All Graphite data is encrypted. The user is able to encrypt and decrypt based on a key pair that is generated client-side and only accessible when the user logs into the app at that specific app origin.

So, if Graphite goes belly up and the user wants to get ahold of that data they stored in Graphite, they go to Box and boom, it’s all there. One problem…

That data can only be decrypted using a privateKey that is no longer accessible.

I want to make this possible for people not because I’m worried about Graphite going under but because I want to help achieve the full data portability without app reliance.

Would love to get some thoughts on what would be necessary to make decrypting data outside of the app from which it was encrypted possible without sacrificing security.


Hey @jehunter5811

Currently, there’s no UI/tool for accessing that key for the user themselves, however, there is code coming soon in blockstack.js which would support allowing a user who controls their root private key (12-word phrase):

import {BlockstackWallet} from blockstack
import bip39 from bip39

// first identity address
var identityIndex = 0

var seed = bip39.mnemonicToSeed('apple apple apple')
var wallet = BlockstackWallet.fromSeedBuffer(seed)
var identityKeys = wallet.getIdentityKeyPair(identityIndex, true)
// get the app-specific private key
var appPrivateKey = wallet.getAppPrivateKey(identityKeys.appsNodeKey,

This is added in this PR:

It’s currently unclear how we’d want to incorporate this kind of feature (exporting a given app-specific private key) into the browser or some other user-facing tooling.


Actually, the CLI can do this. Will push an update later today and an explainer here.


Thanks @aaron and @jude! I’m glad y’all have been thinking about this too!


Should be pushed now. You can use the get_app_keys command in the CLI to generate application keys from your 12-word phrase and the ID-address you use to log in. Example:

$ blockstack-cli get_app_keys  "one race buffalo dynamic icon drip width lake extra forest fee kit" ID-19veSw4r1aUG4GcrZFQUD7YZa1v2es2j6s
  "keyInfo": {
    "privateKey": "TODO",
    "address": "TODO"
  "legacyKeyInfo": {
    "privateKey": "7e7cb91fb810496498f55517291cffaef41e7b36be69fbc7606564e8eefd6a91",
    "address": "1Hf8pNhBPy4MwQpc8q1a9gBmc33thM338V"
  "ownerKeyIndex": 0

Right now, you want the key in the legacyKeyInfo object. We’re going to change the key derivation path in the near future (see this issue), and both derivation paths will be supplied by this tool. You’ll be able to tell which private key to use by looking at the address field and matching it to the address in the Gaia hub URL in the user’s profile’s apps field.

Regarding the larger problem of data portability, the merger of the code for the /list-files/ endpoint to Gaia’s develop branch as well as the addition of gaia_getfile, gaia_putfile, and gaia_listfiles commands to the Blockstack CLI should be enough to cobble together a script for migrating data from one Gaia hub to another (or from one application origin to another). I’ll release a tutorial on how to do this once /list-files/ is running in production, and I’ll probably end up adding a gaia_dump and a gaia_migrate command to the CLI to automatically fetch all data from one Gaia hub and upload it all to another.


It would be nice to have a more user-friendly option for this, in case a new app comes along and wants to get permission to use (for example) Graphite’s files. Obviously asking for the twelve word phrase wouldn’t be safe here. I could see this being a browser feature with an extra option during the auth process.


I am also facing a similar situation. I am making an app and I want to give user full control of their data meaning even if the app goes down, they can access their data. I am providing an export feature for that but that won’t be effective in case the app is down. So it would be great if the user has a user-friendly way to access their data from an app in unencrypted form.