<commit_before>h1. The Privly Protocol

This document details the proof-of-concept (0.1) and working draft (1.0) versions of the Privly protocol-- a method for sharing private content via third-party websites without granting content access to the host page.

Version 0.1 establishes the sharing backbone of the Privly system. It facilitates the private sharing of information, but not the secure sharing of information. Version 1.0 outlines the future development of the system with functionality for client-side cryptography. Version 2.0 is a teaser of future directions.

h2. Preliminaries

The "magic" in this system is on the browser side. Version 0.1 is implemented on the "Privly content server":https://github.com/smcgregor/Privly-Web and the "reference browser extension":https://github.com/smcgregor/Privly-Firefox. If you are developing an extension for the Privly system, version 0.1 is a good place to start. It will continue to be supported in subsequent versions.

h2. Version 0.1

The Privly content server is built on a Rails application and follows RESTful principles unless otherwise noted. We assume a familiarity with RESTful principles in this document.

h3. Authentication

Reading protected content and posting content to the server requires a user account, and user accounts are identified by appending all extension requests with an authentication token, "?auth_token=". The content server authenticates using the Rails gem "Devise":https://github.com/plataformatec/devise. "This page":https://priv.ly/token_authentications/new contains two forms that will return new authentication tokens for extensions. You can adapt these forms for your extension. Please note that generating a new token will invalidate your old token.

h3. Content Parameters

All Privly content in 0.1 is in the posts endpoint. New posts expect the following parameters:
* auth_token
** See "Authentication" above. This ties the content to a user account.
* public
** an optional boolean value indicating whether the content should be public by default.
* content
** Text in "markdown format":http://daringfireball.net/projects/markdown/

After the content is posted to the server you will be redirected to the show action for the content. The show action sets a header "privlyurl," which contains the url of the post.

h3. Display URLs

After the page load event Privly extensions perform the following actions:
# Convert all plaintext priv.ly links to anchor tags.
# Correct link indirection by replacing the href element of anchor tags with the proper Privly URL. For an example, look at what Twitter does to their links.
# Replace the content with an iframe for that content:
** https://priv.ly/posts/#.iframe?frame_id=Alphanumeric

frame_id is an optional parameter that is attached to an event, "IframeResizeEvent,":https://github.com/smcgregor/Privly-web/blob/master/app/views/posts/_iframe_script.html.erb that is fired by the loaded iframe. The IframeResizeEvent also contains a value for "height" that should be used by the extension to set the height of the content's host iframe.

h3. Sharing

Version 0.1 can limit sharing capabilities to a list of email addresses. Email shares are at the /email_shares endpoint.

h2. Version 1.0, Working Draft

The following conventions are under development, meaning you can help develop this part of the system, but don't expect your extension will work with these endpoints yet.

h3. URL Structures

Each of these endpoints have different security arrangements, and collectively cover most secure sharing needs. The steps below the URL format outline what an extension would do when it encounters the URL.

_________________________________
LEVEL 0: Intermediary with Access

h3. https://priv.ly/posts/
* Parameter: Post Identifier

# The extension asks Privly for the content, which the user may or may not have access to

h3. https://priv.ly/distributed
* Parameter: Content Host (example: contenthost.org/privly/####?optional_additional_auth=)

# The extension checks the user preferences and the privacy status of contenthost.org
# The extension decides which identities it will assert for the link and sends them to Privly
# Privly signs the requested identities and a timestamp and returns the signature to the extension
# The extension then requests the content from contenthost.org

_______________________________________________
LEVEL 1: Separation of Content and Cryptography

In this level of security and privacy, the link contains either the cipher text or the decryption key, and the link points to the server with the identified cipher text or decryption key. This level preserves content readability without needing an extension or user account, but the remote server only needs the link to have access to the cleartext.

h3. https://priv.ly/cipher_text/
* Parameter: Post Identifier
* Parameter: PGP Key

# The extension asks Privly for the cipher text, which the user may or may not have access to
# The extension decrypts the content according to the key on the url

h3. https://priv.ly/private_key/
* Parameter: Key Identifier
* Parameter: Cipher Text

# The extension asks Privly for the decryption key, which the user may or may not have access to
# The extension decrypts the content from the URL according to the key from the server

h3. https://priv.ly/distributed/cipher_text
* Parameter: Cipher Text Host (example: contenthost.org/privly/####?optional_additional_auth=)
* Parameter: PGP Key

# The extension checks the user preferences and the privacy status of contenthost.org
# The extension decides which identities it will assert for the link and sends them to Privly
# Privly signs the requested identities and a timestamp and returns the signature to the extension
# The extension then requests the cipher text from contenthost.org
# The extension decrypts the content according to the key on the url

h3. https://priv.ly/distributed/private_key
* Parameter: Key Host (example: keyhost.org/privly/####?optional_additional_auth=)
* Parameter: Key Identifier
* Parameter: Cipher Text

# The extension checks the user preferences and the privacy status of keyhost.org
# The extension decides which identities it will assert for the link and sends them to Privly
# Privly signs the requested identities and a timestamp and returns the signature to the extension
# The extension then requests the decryption key from keyhost.org
# The extension decrypts the content according to the returned key

______________________
LEVEL 1.5: Two Parties

In this level of security and privacy, the link points to two different servers and organizations. The individuals or organizations storing the keys and cipher text could collaborate to gain access to the cleartext, but in many cases this would be unlikely. 

h3. https://priv.ly/separation
* Parameter: Cipher Text Host (example: contenthost.org/privly/####?optional_additional_auth=)
* Parameter: Key Host (example: keyhost.org/privly/####?optional_additional_auth=)
* Parameter: Key Identifier
* Parameter: Cipher Text Identifier

# The extension checks the user preferences and the privacy status of contenthost.org and keyhost.org
# The extension decides which identities it will assert for the key and/or content and sends them to Privly
# Privly signs the requested identities and a timestamp and returns the signature to the extension
# The extension then requests the decryption key from keyhost.org
# The extension then requests the cipher text from contenthost.org
# The extension decrypts the content according to the returned key

_____________________________________
LEVEL 2 Intermediaries Have no Access

These links have secondary layer of encryption. Private keys are encrypted according to the public key for a user's encryption wallet. No one but the holder of the key for the wallet can access the clear text decryption keys. The procedures below all assume that the extension has checked out the encryption wallet and decrypted it on the extension.

Sharing procedures in this level are more complex and require the generation of a group key (encrypted and sent to each member's wallet) or keys for every individual that the content is shared with. Sharing procedures will be finalized when the viewing procedures below are finalized. All content can still be viewed on the web server on this level if the user gives the server access to their private keys. Giving the remote server access to private keys is discouraged.

h3. https://priv.ly/cipher_text/
* Parameter: Post Identifier

# The extension asks Privly for the cipher text, which the user may or may not have access to
# The extension decrypts the content according to their private key

h3. https://priv.ly/private_key/
* Parameter: Key Identifier
* Parameter: Cipher Text

# The extension decrypts the key with their private key if they have one
# The extension decrypts the content from the URL

h3. https://priv.ly/distributed/cipher_text
* Parameter: Content Host (example: contenthost.org/privly/####?optional_additional_auth=)
* Parameter: Encrypted PGP Key (encrypted by a public key)

# The extension attempts to decrypt the PGP key in the parameter
# The extension checks the user preferences and the privacy status of contenthost.org
# The extension decides which identities it will assert for the link and sends them to Privly
# Privly signs the requested identities and a timestamp and returns the signature to the extension
# The extension then requests the cipher text from contenthost.org
# The extension decrypts the content according to the key on the url

h3. https://priv.ly/distributed/private_key
* Parameter: Key Host (example: keyhost.org/privly/####?optional_additional_auth=)
* Parameter: Key Identifier
* Parameter: Cipher Text

# The extension checks the user preferences and the privacy status of keyhost.org
# The extension decides which identities it will assert for the link and sends them to Privly
# Privly signs the requested identities and a timestamp and returns the signature to the extension
# The extension then requests the decryption key from keyhost.org
# The extension decrypts the private key
# The extension decrypts the content according to the decrypted private key

h3. https://priv.ly/separation
* Parameter: Cipher Text Host (example: contenthost.org/privly/####?optional_additional_auth=)
* Parameter: Key Host (example: keyhost.org/privly/####?optional_additional_auth=)
* Parameter: Key Identifier
* Parameter: Cipher Text Identifier

# The extension checks the user preferences and the privacy status of contenthost.org and keyhost.org
# The extension decides which identities it will assert for the key and/or content and sends them to Privly
# Privly signs the requested identities and a timestamp and returns the signature to the extension
# The extension then requests the decryption key from keyhost.org
# The extension attempts to decrypt the decryption key
# The extension then requests the cipher text from contenthost.org
# The extension decrypts the content according to the decrypted key


h2. Version 2.0, Teaser

Ubiquitous privacy+security, distributed identity, access tokens, p2p, and site-specific parsers+formatters.<commit_msg>removed outdated concepts, added pitch for people to fork and improve this document<commit_after>h1. The Privly Protocol

This document details the proof-of-concept (0.1) and working draft (1.0) versions of the Privly protocol-- a method for sharing private content via third-party websites without granting content access to the host page.

Version 0.1 establishes the sharing backbone of the Privly system. It facilitates the private sharing of information, but not the secure sharing of information. Version 1.0 outlines the future development of the system with functionality for client-side cryptography. The principal contribution of Privly to date is a method for injecting content into any website. This is how we want to build on that success.

This draft was prepared a while back and does not have all the sharing concepts we wish to implement, and all of the concepts need rigorous review and specification. This document is in a public repository so anyone can make it better, make your criticism known through improvement or tagging the threats to the sharing model in the document.

h2. Preliminaries

The "magic" in this system is on the browser side. Version 0.1 is implemented on the "Privly content server":https://github.com/smcgregor/Privly-Web and the "reference browser extension":https://github.com/smcgregor/Privly-Firefox. If you are developing an extension for the Privly system, version 0.1 is a good place to start. It will continue to be supported in subsequent versions.

h2. Version 0.1

The Privly content server is built on a Rails application and follows RESTful principles unless otherwise noted. We assume a familiarity with RESTful principles in this document.

h3. Authentication

Authentication in a distributed setting needs reworking. This section is targeting a single web application install.

Reading protected content and posting content to the server requires a user account, and user accounts are identified by appending all extension requests with an authentication token, "?auth_token=". The content server authenticates using the Rails gem "Devise":https://github.com/plataformatec/devise. "This page":https://priv.ly/token_authentications/new contains two forms that will return new authentication tokens for extensions. You can adapt these forms for your extension. Please note that generating a new token will invalidate your old token.

h3. Content Parameters

All Privly content in 0.1 is in the posts endpoint. New posts expect the following parameters:
* auth_token
** See "Authentication" above. This ties the content to a user account.
* public
** an optional boolean value indicating whether the content should be public by default.
* content
** Text in "markdown format":http://daringfireball.net/projects/markdown/

After the content is posted to the server you will be redirected to the show action for the content. The show action sets a header "privlyurl," which contains the url of the post.

h3. Display URLs

After the page load event Privly extensions perform the following actions:
# Convert all plaintext priv.ly links to anchor tags.
# Correct link indirection by replacing the href element of anchor tags with the proper Privly URL. For an example, look at what Twitter does to their links.
# Replace the content with an iframe for that content:
** https://priv.ly/posts/#.iframe?frame_id=Alphanumeric

frame_id is an optional parameter that is attached to an event, "IframeResizeEvent,":https://github.com/smcgregor/Privly-web/blob/master/app/views/posts/_iframe_script.html.erb that is fired by the loaded iframe. The IframeResizeEvent also contains a value for "height" that should be used by the extension to set the height of the content's host iframe.

h3. Sharing

Version 0.1 can limit sharing capabilities to a list of email addresses. Email shares are at the /email_shares endpoint.

h2. Version 1.0, Working Draft

The following conventions are under development, meaning you can help develop this part of the system, but don't expect your extension will work with these endpoints yet.

h3. URL Structures

Each of these endpoints have different security arrangements, and collectively cover most secure sharing needs. The steps below the URL format outline what an extension would do when it encounters the URL.

_________________________________
LEVEL 0: Intermediary with Access

h3. https://priv.ly/posts/
* Parameter: Post Identifier

# The extension asks Privly for the content, which the user may or may not have access to

h3. https://priv.ly/distributed
* Parameter: Content Host (example: contenthost.org/privly/####?optional_additional_auth=)

# The extension checks the user preferences and the privacy status of contenthost.org
# The extension then requests the content from contenthost.org

_______________________________________________
LEVEL 1: Separation of Content and Cryptography

In this level of security and privacy, the link contains either the cipher text or the decryption key, and the link points to the server with the identified cipher text or decryption key. This level preserves content readability without needing an extension or user account, but the remote server only needs the link to have access to the cleartext.

h3. https://priv.ly/cipher_text/
* Parameter: Post Identifier
* Parameter: PGP Key

# The extension asks Privly for the cipher text, which the user may or may not have access to
# The extension decrypts the content according to the key on the url

h3. https://priv.ly/private_key/
* Parameter: Key Identifier
* Parameter: Cipher Text

# The extension asks Privly for the decryption key, which the user may or may not have access to
# The extension decrypts the content from the URL according to the key from the server

h3. https://priv.ly/distributed/cipher_text
* Parameter: Cipher Text Host (example: contenthost.org/privly/####?optional_additional_auth=)
* Parameter: PGP Key

# The extension checks the user preferences and the privacy status of contenthost.org
# The extension then requests the cipher text from contenthost.org
# The extension decrypts the content according to the key on the url

h3. https://priv.ly/distributed/private_key
* Parameter: Key Host (example: keyhost.org/privly/####?optional_additional_auth=)
* Parameter: Key Identifier
* Parameter: Cipher Text

# The extension checks the user preferences and the privacy status of keyhost.org
# The extension then requests the decryption key from keyhost.org
# The extension decrypts the content according to the returned key

______________________
LEVEL 1.5: Two Parties

In this level of security and privacy, the link points to two different servers and organizations. The individuals or organizations storing the keys and cipher text could collaborate to gain access to the cleartext, but in many cases this would be unlikely. 

h3. https://priv.ly/separation
* Parameter: Cipher Text Host (example: contenthost.org/privly/####?optional_additional_auth=)
* Parameter: Key Host (example: keyhost.org/privly/####?optional_additional_auth=)
* Parameter: Key Identifier
* Parameter: Cipher Text Identifier

# The extension checks the user preferences and the privacy status of contenthost.org and keyhost.org
# The extension then requests the decryption key from keyhost.org
# The extension then requests the cipher text from contenthost.org
# The extension decrypts the content according to the returned key

_____________________________________
LEVEL 2 Intermediaries Have no Access

These links have secondary layer of encryption. Keys are encrypted according to the public key for a user's encryption wallet. No one but the holder of the key for the wallet can access the clear text decryption keys. The procedures below all assume that the extension has checked out the encryption wallet (from somewhere) and decrypted it on the extension.

Sharing procedures in this level are more complex and require encrypting the keys for each shared individual. Sharing procedures will be finalized when the viewing procedures below are finalized. All content can still be viewed on the web server on this level if the user gives the server access to their private keys and the link. Giving the remote server access to private keys is discouraged.

h3. https://priv.ly/cipher_text/
* Parameter: Post Identifier

# The extension asks Privly for the cipher text, which the user may or may not have access to
# The extension decrypts the content according to their private key

h3. https://priv.ly/private_key/
* Parameter: Key Identifier
* Parameter: Cipher Text

# The extension decrypts the key with their private key if they have one
# The extension decrypts the content from the URL

h3. https://priv.ly/distributed/cipher_text
* Parameter: Content Host (example: contenthost.org/privly/####?optional_additional_auth=)
* Parameter: Encrypted PGP Key (encrypted by a public key)

# The extension attempts to decrypt the PGP key in the parameter
# The extension checks the user preferences and the privacy status of contenthost.org
# The extension then requests the cipher text from contenthost.org
# The extension decrypts the content according to the key on the url

h3. https://priv.ly/distributed/private_key
* Parameter: Key Host (example: keyhost.org/privly/####?optional_additional_auth=)
* Parameter: Key Identifier
* Parameter: Cipher Text

# The extension checks the user preferences and the privacy status of keyhost.org
# The extension then requests the decryption key from keyhost.org
# The extension decrypts the private key
# The extension decrypts the content according to the decrypted private key

h3. https://priv.ly/separation
* Parameter: Cipher Text Host (example: contenthost.org/privly/####?optional_additional_auth=)
* Parameter: Key Host (example: keyhost.org/privly/####?optional_additional_auth=)
* Parameter: Key Identifier
* Parameter: Cipher Text Identifier

# The extension checks the user preferences and the privacy status of contenthost.org and keyhost.org
# The extension then requests the decryption key from keyhost.org
# The extension attempts to decrypt the decryption key
# The extension then requests the cipher text from contenthost.org
# The extension decrypts the content according to the decrypted key


h2. Version 2.0, Teaser

Ubiquitous privacy+security, distributed identity, access tokens, p2p, and site-specific parsers+formatters.
{'fraction_non_alphanumeric': 0.04944673364507616, 'fraction_numerical': 0.0047224408537432285, 'mean_word_length': 4.856832971800434, 'pattern_counts': {'":': 12, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 36, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1593729', 'n_tokens_mistral': 5293, 'n_tokens_neox': 5105, 'n_words': 2926}