diff --git a/docs/content/sftp.md b/docs/content/sftp.md
index d173705d2..188a8b5fc 100644
--- a/docs/content/sftp.md
+++ b/docs/content/sftp.md
@@ -21,17 +21,14 @@ Here is an example of making a SFTP configuration.  First run
 
     rclone config
 
-This will guide you through an interactive setup process.  You will
-need your account number (a short hex number) and key (a long hex
-number) which you can get from the SFTP control panel.
+This will guide you through an interactive setup process.
+
 ```
 No remotes found - make a new one
 n) New remote
-r) Rename remote
-c) Copy remote
 s) Set configuration password
 q) Quit config
-n/r/c/s/q> n
+n/s/q> n
 name> remote
 Type of storage to configure.
 Choose a number from below, or type in your own value
@@ -63,6 +60,8 @@ Choose a number from below, or type in your own value
    \ "sftp"
 14 / Yandex Disk
    \ "yandex"
+15 / http Connection
+   \ "http"
 Storage> sftp
 SSH host to connect to
 Choose a number from below, or type in your own value
@@ -70,21 +69,24 @@ Choose a number from below, or type in your own value
    \ "example.com"
 host> example.com
 SSH username, leave blank for current username, ncw
-user> 
+user> sftpuser
 SSH port, leave blank to use default (22)
 port> 
-SSH password, leave blank to use ssh-agent
+SSH password, leave blank to use ssh-agent.
 y) Yes type in my own password
 g) Generate random password
 n) No leave this optional password blank
 y/g/n> n
+Path to unencrypted PEM-encoded private key file, leave blank to use ssh-agent.
+key_file> 
 Remote config
 --------------------
 [remote]
 host = example.com
-user = 
+user = sftpuser
 port = 
 pass = 
+key_file = 
 --------------------
 y) Yes this is OK
 e) Edit this remote
@@ -111,6 +113,34 @@ excess files in the directory.
 
     rclone sync /home/local/directory remote:directory
 
+### SSH Authentication ###
+
+The SFTP remote supports 3 authentication methods
+
+  * Password
+  * Key file
+  * ssh-agent
+
+Key files should be unencrypted PEM-encoded private key files.  For
+instance `/home/$USER/.ssh/id_rsa`.
+
+If you don't specify `pass` or `key_file` then it will attempt to
+contact an ssh-agent.
+
+### ssh-agent on macOS ###
+
+Note that there seem to be various problems with using an ssh-agent on
+macOS due to recent changes in the OS.  The most effective work-around
+seems to be to start an ssh-agent in each session, eg
+
+    eval `ssh-agent -s` && ssh-add -A
+
+And then at the end of the session
+
+    eval `ssh-agent -k`
+
+These commands can be used in scripts of course.
+
 ### Modified time ###
 
 Modified times are stored on the server to 1 second precision.
diff --git a/sftp/sftp.go b/sftp/sftp.go
index 77df26365..a0f6254b6 100644
--- a/sftp/sftp.go
+++ b/sftp/sftp.go
@@ -6,6 +6,7 @@ package sftp
 
 import (
 	"io"
+	"io/ioutil"
 	"os"
 	"path"
 	"time"
@@ -40,9 +41,13 @@ func init() {
 			Optional: true,
 		}, {
 			Name:       "pass",
-			Help:       "SSH password, leave blank to use ssh-agent",
+			Help:       "SSH password, leave blank to use ssh-agent.",
 			Optional:   true,
 			IsPassword: true,
+		}, {
+			Name:     "key_file",
+			Help:     "Path to unencrypted PEM-encoded private key file, leave blank to use ssh-agent.",
+			Optional: true,
 		}},
 	}
 	fs.Register(fsi)
@@ -79,6 +84,7 @@ func NewFs(name, root string) (fs.Fs, error) {
 	host := fs.ConfigFileGet(name, "host")
 	port := fs.ConfigFileGet(name, "port")
 	pass := fs.ConfigFileGet(name, "pass")
+	keyFile := fs.ConfigFileGet(name, "key_file")
 	if user == "" {
 		user = os.Getenv("USER")
 	}
@@ -91,7 +97,9 @@ func NewFs(name, root string) (fs.Fs, error) {
 		HostKeyCallback: ssh.InsecureIgnoreHostKey(),
 		Timeout:         fs.Config.ConnectTimeout,
 	}
-	if pass == "" {
+
+	// Add ssh agent-auth if no password or file specified
+	if pass == "" && keyFile == "" {
 		sshAgentClient, _, err := sshagent.New()
 		if err != nil {
 			return nil, errors.Wrap(err, "couldn't connect to ssh-agent")
@@ -100,22 +108,31 @@ func NewFs(name, root string) (fs.Fs, error) {
 		if err != nil {
 			return nil, errors.Wrap(err, "couldn't read ssh agent signers")
 		}
-		/*
-			for i, signer := range signers {
-				if 2*i < len(signers) {
-					signers[i] = signers[len(signers)-i-1]
-					signers[len(signers)-i-1] = signer
-				}
-			}
-		*/
 		config.Auth = append(config.Auth, ssh.PublicKeys(signers...))
-	} else {
+	}
+
+	// Load key file if specified
+	if keyFile != "" {
+		key, err := ioutil.ReadFile(keyFile)
+		if err != nil {
+			return nil, errors.Wrap(err, "failed to read private key file")
+		}
+		signer, err := ssh.ParsePrivateKey(key)
+		if err != nil {
+			return nil, errors.Wrap(err, "failed to parse private key file")
+		}
+		config.Auth = append(config.Auth, ssh.PublicKeys(signer))
+	}
+
+	// Auth from password if specified
+	if pass != "" {
 		clearpass, err := fs.Reveal(pass)
 		if err != nil {
 			return nil, err
 		}
 		config.Auth = append(config.Auth, ssh.Password(clearpass))
 	}
+
 	sshClient, err := ssh.Dial("tcp", host+":"+port, config)
 	if err != nil {
 		return nil, errors.Wrap(err, "couldn't connect ssh")