Check out S3 Pro - the most powerful S3 Client for macOS 11 Big Sur

Managing files via the command-line

We just pushed out version 0.0.5 of our [Strongspace Ruby Gem]( and command line utility – this adds the ability to upload, download, mkdir and delete files and folders from the command line. Since it is all in Ruby it works great on Mac, Windows, Linux and Solaris or wherever else you’ve got Ruby.

To install or update run `sudo gem install strongspace`

The updated command set:

$ strongspace help
=== General Commands
help # show this usage
version # show the gem version

upload # upload a file
download # download a file from Strongspace to the current directory
mkdir # create a folder on Strongspace
delete # delete a file or recursively delete a folder on Strongspace

keys # show your user’s public keys
keys:add [] # add a public key
keys:remove # remove a key by id
keys:clear # remove all keys

spaces # show your user’s spaces
spaces:create [type] # add a new space. type => (normal,public,backup)
spaces:delete [type] # remove a space by and destroy its data
spaces:snapshots # show a space’s snapshots
spaces:create_snapshot # take a space of a space.
spaces:delete_snapshot # remove a snapshot from a space

Strongspace SSH Keys API

Here is the API for listing, creating and removing [SSH Keys]( Successful API calls return HTTP status codes in the 200s and errors have codes 400 and higher. This will be documented more fully in the future when we’ve settled on all the error codes across a wider array of functions.

The [prettyjson]( command is optional, just for readability.
List your SSH Keys

GET /api/v1/ssh_keys


curl -u hemancuso/token:***** | prettyjson
“ssh_keys”: [
“name”: “jmancuso@mactop.local”,
“key”: “ssh-rsa AAAAB3NzaC1yc2EAAAABIw……Az4GLQHoVcyw== jmancuso@mactop.local”,
“id”: 1
“name”: “”,
“key”: “ssh-dss AAAAB3NzaC…ovUGhwtD41cHgxEzBeVvjkcN4=”,
“id”: 2
] }

Add SSH key

POST /api/v1/ssh_keys
:name [optional – key nickname]


curl -u hemancuso/token:***** -F ‘key=ssh-dss AAAAB3NzaC1kc3MAAACBAL….HgxEzBeVvjkcN4=’
{“status”: “ok”}

If the key already exits, it returns an error code and the body:

{“status”:”duplicate key”}

Delete SSH key

DELETE /api/v1/ssh_keys/:id


curl -X DELETE -u hemancuso/token:*****
{“status”: “ok”}

If the key doesn’t exist or user doesn’t have access:

{“status”: “permission denied”}

Strongspace API Authentication

This is the first public facing API we’ve developed and we spent considerable effort examining other successful APIs for inspiration. We wanted an intuitive [RESTful]( API that always returned JSON and didn’t have a bunch of crufty stuff surrounding every request. APIs which require a bunch of custom headers on every request or have [uncommon authentication schemes]( present a significant barrier to entry to the average programmer unless a robust client library already exists in their favorite language.

For authentication, we really like [Github’s]( model. All authentication happens via HTTP basic over HTTPS and can take two forms. First, you can authenticate your regular username and password. Or, you can use an API token as your password and add “/token” to your username, just like Github. Unlike Github, if you change your password for Strongspace, your API token does not change. Also all Strongspace API requests must be performed via HTTPS.

To retrieve your API token:

GET /api/v1/api_token
:reset = “true” [optional – generates a new API token]


curl -u username:password
curl -u username:password

returns the JSON:


Strongspace API and command-line utility

We’ve been working hard for the past couple weeks putting together a REST API for Strongspace and I’m going to write a series of posts this week documenting and showing how to use it. The easiest way to get going is to try out our [Gem]( which includes a command-line utility named ‘strongspace’. To install the gem fire up a terminal and type

`gem install strongspace`

This installs the Strongspace library and makes accessible a `strongspace` command that you can call

`$ strongspace help` prints a list of available commands

=== General Commands

help # show this usage
version # show the gem version

keys # show your user’s public keys
keys:add [] # add a public key
keys:remove # remove a key by id
keys:clear # remove all keys

spaces # show your user’s spaces
spaces:create [type] # add a new space. type => (normal,public,backup)
spaces:destroy [type] # remove a space by and destroy its data
spaces:snapshots # show a space’s snapshots
spaces:create_snapshot # take a space of a space.
spaces:destroy_snapshot # remove a snapshot from a space

Much more coming soon, stay tuned.

ExpanDrive and the Mac App Store

Yesterday Apple announced that the App Store was coming to the Mac. Exciting news for app developers, but much more exciting for the [3.89 million]( new Mac owners every quarter trying to discover, install and keep software up to date. Not unsurprisingly, there is a laundry list of restrictions and requirements for apps trying to make it into the App Store. That list, while not yet formally published, has been [leaked]( It looks as if section 2.18 will keep apps that rely on kernel extensions, like ExpanDrive, which relies on [MacFUSE](, out of the App Store or require developers to create watered down App Store Only forks of their product.

Section 2.18:
> Apps that install kexts will be rejected

We hope this means “Apps that install kernel extensions globally into /System will be rejected” (which we currently do) and not “Apps that load non-Apple kernel extensions will be rejected” If this is an issue about packaging, then namespacing a kernel extension to an app and keeping it inside the bundle is a reasonable request and and something we’ll likely do anyways. It would be a real disappointment if Apple starts to lock down the Mac as it continues to progress towards iOS/OS X unity. Perhaps this is much ado about nothing and it’ll merely require us not to install anything globally, but it’s hard to imagine that will be the case.

ExpanDrive v2.1.2 released

Windows users – we haven’t forgotten about you! The 2.0 client is coming along nicely. Mac users, we have another small update to ExpanDrive that fixes a few bugs and makes Strongspace auto-licensing work more easily. As always, the release notes are [here]( and the update can grabbed via the auto-updater in the preferences pane.

  • NEWStrongspace licensing works for SFTP drives connected directly to Strongspace
  • FIXED Certain FTP servers would not connect with the message ‘Data connection failed'”.

Offsite MySQL backup to Strongspace

You should be doing offsite MySQL backup. Replication is nice, but a corrupted master means a corrupted replica. Thankfully, automated offsite MySQL backup to Strongspace is fairly simple. You write the contents of your database to disk using `mysqldump` and push the dumpfile off to Strongspace with [rsync](

### Basic MySQL backup

On the MySQL server, create a folder to store the backup files

> $ mkdir -p ~/backup/mysql/

Dump the contents of your database to that folder and compress with gzip

> mysqldump –user=USERNAME –password=PASSWORD DATABASE_NAME | gzip > “DATABASE_NAME – `date +%F %T`.sql.gz”

[mysqldump]( has a bunch of option, but this is the most basic form and should work well in most cases. Check `mysqldump –help` if you want to tweak something or are having trouble.

Now push the backup off to Strongspace

>rsync -avz ~/backup/mysql

### Automating the backup

With the basic backup process is working, let’s roll it into a small script that to run nightly with [cron]( To start, you will probably want to setup [password-less login]( to avoid putting your Strongspace password in the script. Put this script in `~/backup/`, substituting your information in the configuration section.

### Configuration
#### Do the backup. Note: use absolute paths for mysqldump/gzip/find/rsync
/opt/local/bin/mysqldump --user=${MYSQL_USERNAME} --password=${MYSQL_PASSWORD} ${MYSQL_DATABASE} | /usr/bin/gzip > "${BACKUP_DIR}/${MYSQL_DATABASE} - `date +%F %T`.sql.gz"
# remove backups that are more than 2 weeks old
/usr/xpg4/bin/find . -mtime +14 -exec rm {} ;
# Push the backups off to Strongspace

Next, we want to make the script executable, and visible by no-one else.

> $ chmod 700 ~/backup/

Run the script and make sure everything works. If everything worked it won’t output any error message and a new backup will have arrived on Strongspace

> $ ~/backup/

Schedule to run that job every night at midnight using cron. Run `crontab` and add a line like this

> 0 0 * * * /user/home/somebody/backup/

As always, test the [restore process]( A backup that doesn’t correctly restore isn’t a backup.

A little Strongspace bash-fu

Last week Brett Terpstra came up with a [simple bash function]( to push any file to your [Public space]( and give back a [TinyURL]( to that file on your clipboard. I cleaned it up a bit and thought it worthy of its own post.

Paste this function into an open Terminal window or add it to the end of `/.profile`. Make sure to substitute `your_username` with your Strongspace username.

function sshare () {
  scp "$1" ss:/strongspace/your_username/public
  tiny=$(curl -s --data-urlencode "url=$url"
  echo -n $tiny | pbcopy && echo $tiny

This function assumes you have a [ssh alias]( named “ss” setup, but it’s not required. It also is more convenient with [password-less ssh authentication](

Now run `sshare some_filename` to push and host any file off to Strongspace, e.g.

`sshare “Ray LaMontagne – Beg Steal or Borrow.mp3″`

Multi-user Strongspace collaboration with Spaces

… re-blogged from our [Strongspace Blog](

Strongspace has top level folders called Spaces. You’ll see your spaces listed in the sidebar on left-hand side of the files browser. Think of them as regular folders that you can set special permissions so that you can collaborate on your data both via the web or SFTP. You can even set up a shared network drive using [ExpanDrive]( Create a new space by clicking the plus button ‘‘ to the right of “Your Spaces” and picking a name.

### Adding a collaborator to a space

Giving a friend, family member or co-worker access to a space is simple. Click the gear icon ‘‘ next to person you want to share your data with and hit “Add.” An invitation will be sent to the email address you typed, prompting the user to set a new password. They now have their own [free] Strongspace account along with access to the data you shared with them.

### Connecting via SFTP/rsync to a shared space

Let’s say that the user “expandrive” shared their home space with you. To get at that data via SFTP you’d connect to the server `` and the data would be at the path `/strongspace/expandrive/home`

### The Future of Spaces
Right now spaces are just folders in the top level of your filesystem. Going forward we’ll be introducing fancy spaces that have a variety of cool features attached to them. The first of these fancy spaces is actually your [Public space](/blog/simple-asset-hosting-with-your-public-space) – it has the property that all the contents are automatically shared/hosted to the world by default. Our plan is to introduce fancy spaces for photo galleries, music, source code repositories and more.

Basic SFTP access to Strongspace

One of the best and most unique features of Strongspace is SFTP access. This lets you connect to your data using any of hundreds of awesome clients on any platform, on any device. Setting it up is simple, you’d connect with your normal Strongspace credentials directly to the filesystem you want access to.

### Login details

> Server –
> Username – your Strongspace username
> Password – your Strongspace password

Where `username` is your Strongspace username. To connect directly to a specific space set the remote path directly to that space, with the following format:


### Example

If you wanted to connect to the “music” space of “expandrive” you would connect to


using your normal Strongspace username and password with the remote path set to:

> /strongspace/expandrive/music