<blockquote>
<p><em>This is a Bisq Network proposal. Please familiarize yourself with the <a href="https://docs.bisq.network/proposals.html" rel="nofollow">submission and review process</a>.</em></p>
</blockquote>
<h2>Introduction</h2>
<p>There is a work on exposing some of the Bisq functionality for external programatic access over HTTP API.<br>
The API might be used by local scripts or programs or by remote clients, like a mobile app.</p>
<p>This proposal presents how to access API in a secure manner over TOR and using password and token based authentication.</p>
<p><a target="_blank" rel="noopener noreferrer" href="https://user-images.githubusercontent.com/431064/51472023-9e434300-1d78-11e9-900d-adbce651e086.png"><img src="https://user-images.githubusercontent.com/431064/51472023-9e434300-1d78-11e9-900d-adbce651e086.png" alt="Bisq HTTP API network diagram" style="max-width:100%;"></a></p>
<h2>Local access</h2>
<p>API exposes an HTTP port bound to localhost only.<br>
We do not use SSL because it would force every user to get an SSL certificate, which in turn requires a registered domain name.</p>
<hr>
<p><strong>Important assumption</strong></p>
<p>We assume that local machine is not compromised and local traffic is not being listened by any malicious actors.</p>
<hr>
<p>In order to protect from CSRF attack (i.e. user visits website with hidden image linking to <a href="http://localhost:8080" rel="nofollow">http://localhost:8080</a>)<br>
every request needs to have <code>Authorization</code> header which contains access token.<br>
Access token is generated when user executes request to <code>/user/login</code> endpoint with a valid password.<br>
Access token is stored only in process memory.<br>
The password digest (SHA256) and salt (to prevent <a href="https://en.wikipedia.org/wiki/Rainbow_table" rel="nofollow">Rainbow table</a> attack) is stored in Bisq data directory in a dedicated file.</p>
<hr>
<p><em>Side note</em></p>
<p>Initially there was an idea to use wallet password instead separate password for the API, but there might be cases<br>
when users don't want wallet password, which also complicates the startup/restart process as the wallet must be<br>
decrypted before other services are initialized.</p>
<hr>
<h2>Remote access over TOR</h2>
<p>Every service bound to localhost can be exposed over TOR as a <a href="https://www.torproject.org/docs/tor-onion-service" rel="nofollow">hidden service</a>.<br>
Here is a code snipped showing how to publish hidden service that proxies traffic from port 80 (on TOR) to <code>localPort</code>:</p>
<pre><code>private void publishHiddenServiceIfTorEnabled() {
    try {
        Tor tor = Tor.getDefault();
        if (null == tor) {
            return;
        }
        final Integer localPort = bisqEnvironment.getHttpApiPort();
        final HsContainer hsContainer = tor.publishHiddenService$tor("http-api", 80, localPort);
        log.info("HTTP API Tor hostname: {}", hsContainer.getHostname$tor());
    } catch (Throwable ex) {
        throw new RuntimeException(ex);
    }
}
</code></pre>
<h3>Mobile devices</h3>
<p>As of time of this writing, TOR is available only on Android devices.<br>
In order to access the API from mobile device it needs to have <a href="https://guardianproject.info/apps/orbot/" rel="nofollow">Orbot</a> installed.<br>
User can download it from Goolge Play store.<br>
Once Orbot is started user must enable <code>VPN mode</code> and press <code>Start</code> button.<br>
Now the traffic will be directed over TOR and all hidden services will be visible to any application installed on that<br>
mobile device (i.e. user can access the API using the browser).</p>

<p style="font-size:small;-webkit-text-size-adjust:none;color:#666;">—<br />You are receiving this because you are subscribed to this thread.<br />Reply to this email directly, <a href="https://github.com/bisq-network/proposals/issues/69">view it on GitHub</a>, or <a href="https://github.com/notifications/unsubscribe-auth/AkpZtk-cBNOyW7ZYhaH4Ez2VOmdN8H7pks5vFaZLgaJpZM4aKpN9">mute the thread</a>.<img src="https://github.com/notifications/beacon/AkpZtv-hcyrL7DwQVWff4cByq6VJYIfhks5vFaZLgaJpZM4aKpN9.gif" height="1" width="1" alt="" /></p>
<script type="application/json" data-scope="inboxmarkup">{"api_version":"1.0","publisher":{"api_key":"05dde50f1d1a384dd78767c55493e4bb","name":"GitHub"},"entity":{"external_key":"github/bisq-network/proposals","title":"bisq-network/proposals","subtitle":"GitHub repository","main_image_url":"https://github.githubassets.com/images/email/message_cards/header.png","avatar_image_url":"https://github.githubassets.com/images/email/message_cards/avatar.png","action":{"name":"Open in GitHub","url":"https://github.com/bisq-network/proposals"}},"updates":{"snippets":[{"icon":"DESCRIPTION","message":"API security (#69)"}],"action":{"name":"View Issue","url":"https://github.com/bisq-network/proposals/issues/69"}}}</script>
<script type="application/ld+json">[
{
"@context": "http://schema.org",
"@type": "EmailMessage",
"potentialAction": {
"@type": "ViewAction",
"target": "https://github.com/bisq-network/proposals/issues/69",
"url": "https://github.com/bisq-network/proposals/issues/69",
"name": "View Issue"
},
"description": "View this Issue on GitHub",
"publisher": {
"@type": "Organization",
"name": "GitHub",
"url": "https://github.com"
}
}
]</script>