## File: README.md

# SFTPGo

[](https://github.com/drakkan/sftpgo/workflows/CI/badge.svg)
[](https://www.gnu.org/licenses/agpl-3.0)
[](https://github.com/avelino/awesome-go)

Full-featured and highly configurable event-driven file transfer solution. Server protocols: SFTP, HTTP/S, FTP/S, WebDAV. Storage backends: local filesystem, encrypted local filesystem, S3 (compatible) Object Storage, Google Cloud Storage, Azure Blob Storage, other SFTP servers.

With SFTPGo you can leverage local and cloud storage backends for exchanging and storing files internally or with business partners using the same tools and processes you are already familiar with.

## Project Status & Editions

SFTPGo is an open-source project with a sustainable business model. We offer two editions to suit different requirements, ensuring the project remains healthy and maintained for everyone.

### Open Source (Community)

Free, Copyleft (AGPLv3), Community Supported. The Community edition is a fully functional, production-ready solution widely adopted worldwide. It includes all the core protocols, storage backends, and the WebAdmin/WebClient UIs. It is ideal for:

- Standard file transfer needs.
- Integrating storage backends (S3, GCS, Azure Blob) with legacy protocols.
- Projects that are comfortable with AGPLv3 licensing.

### SFTPGo Enterprise

Commercial License, Professional Support, ISO 27001 Vendor. The Enterprise edition is built on the same core but extends it for mission-critical environments, compliance-heavy industries, and advanced workflows. It is a drop-in replacement (seamless upgrade).

| Feature | Open Source (Community) | Enterprise Edition |
| :--- | :--- | :--- |
| **License Type** | AGPLv3 (Copyleft) | **Commercial License**Proprietary/No Copyleft |
| **Vendor Compliance** | Not ApplicableCommunity Project | **Certified Vendor**ISO 27001 & Supply Chain Validation |
| **Support** | Community (GitHub) | **Direct from Authors** |
| **Cloud Storage Engine** | Standard | **High Performance & Scalable**In-memory streaming (no local temp files) and up to 70% faster |
| **High Availability (HA)** | StandardShared DB & Storage | **Advanced**Enhanced event handling and optimized instance coordination |
| **Automation Logic** | Simple Placeholders | **Dynamic Logic & Virtual Folders**Conditions, loops, route data across storage backends |
| **Data Lifecycle** | Delete / Retain | **Smart Archiving**Move data to external Cloud/SFTP storage via Virtual Folders |
| **Email Data Ingestion** | - | **Native IMAP Integration**Auto-extract attachments from email to storage |
| **Public Sharing** | Standard Links | **Advanced & Collaborative**Email Authentication & Group Delegation |
| **Data Protection** | - | **Encryption & Scanning**Automated PGP, Antivirus & DLP via ICAP |
| **Advanced Identity (SSO)** | Standard | **Extended Controls**Advanced Single Sign-On parameters |
| **Document Editing** | - | **Included**View, edit, and co-author in browser |

**Note**: We are committed to keeping the Open Source edition powerful and maintained. The Enterprise edition helps fund the development of the entire SFTPGo ecosystem.

## Sponsors

If you rely on SFTPGo in your projects, consider becoming a [sponsor](https://github.com/sponsors/drakkan).

Your sponsorship helps cover maintenance, security updates and ongoing development of the open-source edition.

### Thank you to our sponsors

#### Platinum sponsors

[](https://www.aledade.com/)

[](https://www.jumptrading.com/)

[](https://wpengine.com/)

#### Silver sponsors

[](https://idcs.ip-paris.fr/)

#### Bronze sponsors

[](https://servinga.com/)

[](https://www.reui.io/)

## Documentation

You can explore all supported features and configuration options at [docs.sftpgo.com](https://docs.sftpgo.com/latest/).

**Note:** The link above refers to the **Community Edition**.
For details on **Enterprise Edition**, please refer to the [Enterprise Documentation](https://docs.sftpgo.com/enterprise/).

## Support

- **Community Support**: use [GitHub Discussions](https://github.com/drakkan/sftpgo/discussions) to ask questions, share feedback, and engage with other users.
- **Commercial Support**: If you require guaranteed SLAs, expert guidance, or the advanced features listed above, check out [SFTPGo Enterprise](https://sftpgo.com).

SFTPGo Enterprise is available as:

- On-premises: Full control on your infrastructure. More details: [sftpgo.com/on-premises](https://sftpgo.com/on-premises)
- Fully managed SaaS: We handle the infrastructure. More details: [sftpgo.com/saas](https://sftpgo.com/saas)

## Internationalization

The translations are available via [Crowdin](https://crowdin.com/project/sftpgo), who have granted us an open source license.

Before translating please take a look at our contribution [guidelines](https://docs.sftpgo.com/latest/web-interfaces/#internationalization).

## Release Cadence

SFTPGo follows a feature-driven release cycle.

- Enterprise Edition: Receives major new features first and follows a faster [release cadence](https://docs.sftpgo.com/enterprise/changelog/).
- Community Edition: Remains maintained, receiving bug fixes, security updates, and updates to core features.

## Acknowledgements

SFTPGo makes use of the third party libraries listed inside [go.mod](./go.mod).

We are very grateful to all the people who contributed with ideas and/or pull requests.

Thank you to [ysura](https://www.ysura.com/) for granting us stable access to a test AWS S3 account.

Thank you to [KeenThemes](https://keenthemes.com/) for granting us a custom license to use their amazing [themes](https://keenthemes.com/bootstrap-templates) for the SFTPGo WebAdmin and WebClient user interfaces, across both the Open Source and Open Core versions.

Thank you to [Crowdin](https://crowdin.com/) for granting us an Open Source License.

Thank you to [Incode](https://www.incode.it/) for helping us to improve the UI/UX.

## License

SFTPGo source code is licensed under the GNU AGPL-3.0-only with [additional terms](./NOTICE).

The [theme](https://keenthemes.com/bootstrap-templates) used in WebAdmin and WebClient user interfaces is proprietary, this means:

- KeenThemes HTML/CSS/JS components are allowed for use only within the SFTPGo product and restricted to be used in a resealable HTML template that can compete with KeenThemes products anyhow.
- The SFTPGo WebAdmin and WebClient user interfaces (HTML, CSS and JS components) based on this theme are allowed for use only within the SFTPGo product and therefore cannot be used in derivative works/products without an explicit grant from the [SFTPGo Team](mailto:support@sftpgo.com).

More information about [compliance](https://sftpgo.com/compliance.html).

**Note:** We do not provide legal advice. If you have questions about license compliance or whether your use case is permitted under the license terms, please consult your legal team.

## Copyright

Copyright (C) 2019 - 2026 Nicola Murino

---

## File: examples/quotascan/README.md

# Update user quota

:warning: Since v2.4.0 you can use the [EventManager](https://docs.sftpgo.com/latest/eventmanager/) to schedule quota scans.

The `scanuserquota` example script shows how to use the SFTPGo REST API to update the users' quota.

The stored quota may be incorrect for several reasons, such as an unexpected shutdown while uploading files, temporary provider failures, files copied outside of SFTPGo, and so on.

A quota scan updates the number of files and their total size for the specified user and the virtual folders, if any, included in his quota.

If you want to track quotas, a scheduled quota scan is recommended. You can use this example as a starting point.

The script is written in Python and has the following requirements:

- python3 or python2
- python [Requests](https://requests.readthedocs.io/en/master/) module

The provided example tries to connect to an SFTPGo instance running on `127.0.0.1:8080` using the following credentials:

- username: `admin`
- password: `password`

Please edit the script according to your needs.

---

## File: examples/php-activedirectory-http-server/README.md

# SFTPGo on Windows with Active Directory Integration + Caddy Static File Server Example

[](https://www.youtube.com/watch?v=M5UcJI8t4AI)

This is similar to the ldapauthserver example, but is more specific to using Active Directory along with using SFTPGo on a Windows Server.

The Youtube Walkthrough/Tutorial video above goes into considerable more detail, but in short, it walks through setting up SFTPGo on a new Windows Server, and enables the External Authentication feature within SFTPGo, along with my `sftpgo-ldap-http-server` project, to allow for user authentication into SFTPGo to occur through one or more Active Directory connections.

Additionally, I go through using the Caddy web server, to help enable serving of static files, if this is something that would be of interest for you.

To get started, you'll want to download the latest release ZIP package from the [sftpgo-ldap-http-server repository](https://github.com/orware/sftpgo-ldap-http-server).

The ZIP itself contains the `sftpgo-ldap-http-server.exe` file, along with an `OpenLDAP` folder (mainly to help if you want to use TLS for your LDAP connections), and a `Data` which contains a logs folder, a configuration.example.php file, a functions.php file, and the LICENSE and README files.

The video above goes through the whole process, but to get started you'll want to install SFTPGo on your server, and then extract the `sftpgo-ldap-http-server` ZIP file on the server as well into a separate folder. Then you'll want to copy the configuration.example.php file and name it `configuration.php` and begin customizing the settings (e.g. add in your own LDAP settings, along with how you may want to have your folders be created). At the very minimum you'll want to make sure that the home directories are set correctly to how you want the folders to be created for your environment (you don't have to use the virtual folders or really any of the other functionality if you don't need it).

Once configured, from a command prompt window, if you are already in the same folder as where you extracted the `sftpgo-ldap-http-server` ZIP, you may simply call the `sftpgo-ldap-http-server.exe` and it should start up a simple HTTP server on Port 9001 running on localhost (the port can be adjusted via the `configuration.php` file as well). Now all you have to do is point SFTPGo's `external_auth_hook` option to point to `http://localhost:9001/` and you should be able to run some authentication tests (assuming you have all of your settings correct and there are no intermediate issues).

The video above definitely goes through some troubleshooting situations you might find yourself coming across, so while it is long (at about 1 hour, 42 minutes), it may be helpful to review and avoid some issues and just to learn a bit more about SFTPGo and the integration above.

## Example Virtual Folders Configuration (Allowing for Both a Public and Private Folder)

The following can be utilized if you'd like to assign your users both a Private Virtual Folder and Public Virtual Folder.

By itself, the Public Virtual Folder isn't necessarily public, so keep that in mind. Only by combining things together with the Caddy web server (and Caddyfile example configuration down below) can you be successful in making the `F:\files\public` folder from the example public.

```php
$virtual_folders['example'] = [
    [
      //"id" => 0,
      "name" => "private-#USERNAME#",
      "mapped_path" => 'F:\files\private\#USERNAME#',
      //"used_quota_size" => 0,
      //"used_quota_files" => 0,
      //"last_quota_update" => 0,
      "virtual_path" => "/_private",
      "quota_size" => -1,
      "quota_files" => -1
    ],
	[
      //"id" => 0,
      "name" => "public-#USERNAME#",
      "mapped_path" => 'F:\files\public\#USERNAME#',
      //"used_quota_size" => 0,
      //"used_quota_files" => 0,
      //"last_quota_update" => 0,
      "virtual_path" => "/_public",
      "quota_size" => -1,
      "quota_files" => -1
    ]
];
```

## Example Connection "Output Object" Allowing For No Files in the User's Home Directory ("Root Directory") but Allowing for Files in the Public/Private Virtual Folders

The magic here happens in the "permissions" value, by limiting the root/home directory to just the list/download permissions, and then allowing all permissions on the Public/Private virtual folders.

```php
$connection_output_objects['example'] = [
    'status' => 1,
    'username' => '',
    'expiration_date' => 0,
    'home_dir' => '',
    'uid' => 0,
    'gid' => 0,
    'max_sessions' => 0,
    'quota_size' => 0,
    'quota_files' => 100000,
    'permissions' => [
        "/" => ["list", "download"],
        "/_private" => ["*"],
        "/_public" => ["*"],
    ],
    'upload_bandwidth' => 0,
    'download_bandwidth' => 0,
    'filters' => [
        'allowed_ip' => [],
        'denied_ip' => [],
    ],
    'public_keys' => [],
];
```

## Recommended Usage of Automatic Groups Mode (Limiting by Group Prefix)

The `sftpgo-ldap-http-server` project is able to automatically create virtual folders for any groups your user is a memberof if the automatic mode is turned on. However, by having a specific set of allowed prefixes defined, you can limit things to just those groups that begin with the prefixes you've listed, which can be helpful. The prefix itself will be removed from the group name when added as a virtual folder for the user.

```php
// If automatic groups mode is disabled, then you have to manually add the allowed groups into $allowed_groups down below:
// If enabled, then any groups you are a memberof will automatically be added in using the template below.
$auto_groups_mode = true;

$auto_groups_mode_virtual_folder_template = [
    [
      //"id" => 0,
      "name" => "groups-#GROUP#",
      "mapped_path" => 'F:\files\groups\#GROUP#',
      //"used_quota_size" => 0,
      //"used_quota_files" => 0,
      //"last_quota_update" => 0,
      "virtual_path" => "/groups/#GROUP#",
      "quota_size" => 0,
      "quota_files" => 100000
    ]
];

// Used only when auto groups mode is enabled and will help prevent all your groups from being
// added into SFTPGo since only groups with the prefixes defined here will be automatically added
// with prefixes automatically removed when listed as a virtual folder (e.g. a group with name
// "sftpgo-example" would simply become "example").
$allowed_group_prefixes = [
    'sftpgo-'
];
```

## Example Caddyfile Configuration You Can Adapt for Your Needs

```shell
### Re-usable snippets:

(add_static_file_serving_features) {

	# Allow accessing files without requiring .html:
	try_files {path} {path}.html

	# Enable Static File Server and Directory Browsing:
	file_server browse

	# Enable templating functionality:
	templates

	# Enable Compression for Output:
	encode zstd gzip

	handle_errors {
		respond "{http.error.status_code} {http.error.status_text}"
	}
}

(add_hsts_headers) {
	header {
		# Enable HTTP Strict Transport Security (HSTS) to force clients to always

		# connect via HTTPS (do not use if only testing)
		Strict-Transport-Security "max-age=31536000; includeSubDomains"

		# Enable cross-site filter (XSS) and tell browser to block detected attacks
		X-XSS-Protection "1; mode=block"

		# Prevent some browsers from MIME-sniffing a response away from the declared Content-Type
		X-Content-Type-Options "nosniff"

		# Disallow the site to be rendered within a frame (clickjacking protection)
		X-Frame-Options "DENY"

		# keep referrer data off of HTTP connections
		Referrer-Policy no-referrer-when-downgrade
	}
}

(add_logging_with_path) {
	log {
		output file "{args.0}" {
			roll_size 100mb
			roll_keep 5
			roll_keep_for 720h
		}

		format json
		#format console
		#format single_field common_log
	}
}

### Site Definitions:

public.example.com {

	# Site Root:
	root * F:\files\public

	import add_logging_with_path "F:\caddy\logs\public_example_com_access.log"
	import add_static_file_serving_features
	import add_hsts_headers
}


### Reverse Proxy Definitions:

webdav.example.com {
	reverse_proxy localhost:9000

	import add_logging_with_path "F:\caddy\logs\webdav_example_com_access.log"
}
```

---

## File: examples/OTP/authy/keyint/README.md

# Authy 2FA using keyboard interactive authentication

This example shows how to authenticate SFTP users using 2FA (password + Authy token). Please read the [sample code](./main.go), it should be self explanatory.

---

## File: examples/OTP/authy/extauth/README.md

# Authy external authentication

This example shows how to use Authy TOTP token as password for SFTPGo users. Please read the [sample code](./main.go), it should be self explanatory.

---

## File: examples/OTP/authy/checkpwd/README.md

# Authy 2FA via check password hook

This example shows how to use 2FA via the check password hook using a password consisting of a fixed part and an Authy TOTP token. The hook will check the TOTP token using the Authy API and SFTPGo will check the fixed part. Please read the [sample code](./main.go), it should be self explanatory.

---

## File: examples/OTP/authy/README.md

# Authy

These example show how-to integrate [Twilio Authy API](https://www.twilio.com/docs/authy/api) for One-Time-Password logins.

The examples assume that the user has the free [Authy app](https://authy.com/) installed and uses it to generate offline [TOTP](https://en.wikipedia.org/wiki/Time-based_One-time_Password_algorithm) codes (soft tokens).

You first need to [create an Authy Application in the Twilio Console](https://twilio.com/console/authy/applications?_ga=2.205553366.451688189.1597667213-1526360003.1597667213), then you can create a new Authy user and store a reference to the matching SFTPGo account.

Verify that your Authy application is successfully registered:

```bash
export AUTHY_API_KEY=<your api key here>
curl 'https://api.authy.com/protected/json/app/details' -H "X-Authy-API-Key: $AUTHY_API_KEY"
```

now create an Authy user:

```bash
curl -XPOST "https://api.authy.com/protected/json/users/new" \
-H "X-Authy-API-Key: $AUTHY_API_KEY" \
--data-urlencode user[email]="user@domain.com" \
--data-urlencode user[cellphone]="317-338-9302" \
--data-urlencode user[country_code]="54"
```

The response is something like this:

```json
{"message":"User created successfully.","user":{"id":xxxxxxxx},"success":true}
```

Save the user id somewhere and add a reference to the matching SFTPGo account. You could also store this ID in the `additional_info` SFTPGo user field.

After this step you can use the Authy app installed on your phone to generate TOTP codes.

Now you can verify the token using an HTTP GET request:

```bash
export TOKEN=<TOTP you read from Authy app>
export AUTHY_ID=
curl -i "https://api.authy.com/protected/json/verify/${TOKEN}/${AUTHY_ID}" \
    -H "X-Authy-API-Key: $AUTHY_API_KEY"
```

So inside your hook you need to check:

- the HTTP response code for the verify request, it must be `200`
- the JSON response body, it must contains the key `success` with the value `true` (as string)

If these conditions are met the token is valid and you allow the user to login.

We provide the following examples:

- [Keyboard interactive authentication](./keyint/README.md) for 2FA using password + Authy one time token.
- [External authentication](./extauth/README.md) using Authy one time tokens as passwords.
- [Check password hook](./checkpwd/README.md) for 2FA using a password consisting of a fixed string and a One Time Token.

Please note that these are sample programs not intended for production use, you should write your own hook based on them and you should prefer HTTP based hooks if performance is a concern.

:warning: SFTPGo has also built-in 2FA support.

---

## File: examples/ldapauthserver/README.md

# LDAPAuthServer

This is an example for an HTTP server to use as external authentication HTTP hook. It performs authentication against an LDAP server.
It is tested against [389ds](https://directory.fedoraproject.org/) and can be used as starting point to authenticate using any LDAP server including Active Directory.

You can configure the server using the [ldapauth.toml](./ldapauth.toml) configuration file.
You can build this example using the following command:

```console
go build -ldflags "-s -w" -o ldapauthserver
```

:warning: A plugin for LDAP/Active Directory authentication is also [available](https://github.com/sftpgo/sftpgo-plugin-auth).

---

## File: examples/ldapauth/README.md

# LDAPAuth

This is an example for an external authentication program. It performs authentication against an LDAP server.
It is tested against [389ds](https://directory.fedoraproject.org/) and can be used as starting point to authenticate using any LDAP server including Active Directory.

You need to change the LDAP connection parameters and the user search query to match your environment.
You can build this example using the following command:

```console
go build -ldflags "-s -w" -o ldapauth
```

This program assumes that the 389ds schema was extended to add support for public keys using the following ldif file placed in `/etc/dirsrv/schema/98openssh-ldap.ldif`:

```console
dn: cn=schema
changetype: modify
add: attributetypes
attributetypes: ( 1.3.6.1.4.1.24552.500.1.1.1.13 NAME 'sshPublicKey' DESC 'MANDATORY: OpenSSH Public key' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )
-
add: objectclasses
objectClasses: ( 1.3.6.1.4.1.24552.500.1.1.2.0 NAME 'ldapPublicKey' SUP top AUXILIARY DESC 'MANDATORY: OpenSSH LPK objectclass' MUST ( uid ) MAY ( sshPublicKey ) )
-

dn: cn=sshpublickey,cn=default indexes,cn=config,cn=ldbm database,cn=plugins,cn=config
changetype: add
cn: sshpublickey
nsIndexType: eq
nsIndexType: pres
nsSystemIndex: false
objectClass: top
objectClass: nsIndex

dn: cn=sshpublickey_self_manage,ou=groups,dc=example,dc=com
changetype: add
objectClass: top
objectClass: groupofuniquenames
cn: sshpublickey_self_manage
dn: dc=example,dc=com
changetype: modify
add: aci
aci: (targetattr = "sshPublicKey") (version 3.0; acl "Allow members of sshpublickey_self_manage to edit their keys"; allow(write) (groupdn = "ldap:///cn=sshpublickey_self_manage,ou=groups,dc=example,dc=com" and userdn="ldap:///self" ); )
-
```

:warning: A plugin for LDAP/Active Directory authentication is also [available](https://github.com/sftpgo/sftpgo-plugin-auth).