[OAUTH-WG] OAuth2 Implementation questions (client secret and refresh tokens)

Dave Rochwerger <daver@quizlet.com> Wed, 07 September 2011 21:14 UTC

Return-Path: <daver@quizlet.com>
X-Original-To: oauth@ietfa.amsl.com
Delivered-To: oauth@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id D380921F8D38 for <oauth@ietfa.amsl.com>; Wed, 7 Sep 2011 14:14:31 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -2.976
X-Spam-Level:
X-Spam-Status: No, score=-2.976 tagged_above=-999 required=5 tests=[BAYES_00=-2.599, FM_FORGED_GMAIL=0.622, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_LOW=-1]
Received: from mail.ietf.org ([12.22.58.30]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id OSlV47w7gT1s for <oauth@ietfa.amsl.com>; Wed, 7 Sep 2011 14:14:30 -0700 (PDT)
Received: from mail-yx0-f172.google.com (mail-yx0-f172.google.com [209.85.213.172]) by ietfa.amsl.com (Postfix) with ESMTP id BFF4E21F8D02 for <oauth@ietf.org>; Wed, 7 Sep 2011 14:14:30 -0700 (PDT)
Received: by yxj20 with SMTP id 20so81957yxj.31 for <oauth@ietf.org>; Wed, 07 Sep 2011 14:16:21 -0700 (PDT)
Received: by 10.101.144.18 with SMTP id w18mr5294913ann.133.1315430180898; Wed, 07 Sep 2011 14:16:20 -0700 (PDT)
Received: from mail-gx0-f181.google.com (mail-gx0-f181.google.com [209.85.161.181]) by mx.google.com with ESMTPS id 11sm2252896ant.0.2011.09.07.14.16.19 (version=SSLv3 cipher=OTHER); Wed, 07 Sep 2011 14:16:20 -0700 (PDT)
Received: by gxk9 with SMTP id 9so286216gxk.40 for <oauth@ietf.org>; Wed, 07 Sep 2011 14:16:19 -0700 (PDT)
Received: by 10.101.176.12 with SMTP id d12mr19332anp.100.1315430179214; Wed, 07 Sep 2011 14:16:19 -0700 (PDT)
MIME-Version: 1.0
Received: by 10.100.164.3 with HTTP; Wed, 7 Sep 2011 14:15:59 -0700 (PDT)
X-Originating-IP: [67.169.69.75]
In-Reply-To: <CAGyXixwZhMMTzWPrMeWQZEz0v_9WYGwPVByGfPAxGnAthf=3Ng@mail.gmail.com>
References: <CAGyXixwZhMMTzWPrMeWQZEz0v_9WYGwPVByGfPAxGnAthf=3Ng@mail.gmail.com>
From: Dave Rochwerger <daver@quizlet.com>
Date: Wed, 07 Sep 2011 14:15:59 -0700
Message-ID: <CAGyXixzH6uwf72ons1UE2-yKfx=TK-bSBSpN5TzmcJNPVcbxKg@mail.gmail.com>
To: oauth@ietf.org
Content-Type: multipart/alternative; boundary="001636c9274b8f158c04ac607430"
Cc: Quizlet Dev Team <devteam@quizlet.com>
Subject: [OAUTH-WG] OAuth2 Implementation questions (client secret and refresh tokens)
X-BeenThere: oauth@ietf.org
X-Mailman-Version: 2.1.12
Precedence: list
List-Id: OAUTH WG <oauth.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/oauth>, <mailto:oauth-request@ietf.org?subject=unsubscribe>
List-Archive: <http://www.ietf.org/mail-archive/web/oauth>
List-Post: <mailto:oauth@ietf.org>
List-Help: <mailto:oauth-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/oauth>, <mailto:oauth-request@ietf.org?subject=subscribe>
X-List-Received-Date: Wed, 07 Sep 2011 21:14:31 -0000

Hi all,

I have been implementing OAuth2 based on the various drafts for our new API.
Initially, I implemented everything as per the spec, but due to our
particular scenario and restrictions we have in place, there are some
fundamental questions that I am unable to defend.

I am hoping this group could help answer them for me.

Our scenario:
==========
* We are implementing an API to allow 3rd party developers to access users'
protected resources via their applications. The applications will mostly be
native phone apps, but some will have web server backends (javascript-only
applications are not a concern at the moment).
* We want to provide very long-lived (forever) tokens.
* We are implementing the "authorization code" flow as that seems best
suited to us (we don't want the implicit flow because end-users would have
to re-authorize every hour).

Our architecture:
============
* We control both the API server and the authorization server.
* All requests to protected resources (ie: to the API server) are always
done over SSL.
* All requests to the authz server (token and authorize endpoints) are
always done over SSL.
* We enforce that every client must supply the state parameter (and our
guidelines say they must verify the state for CSRF mitigation).
* We enforce that every client must register a redirect URI.
* We validate the redirect_uri used to request an access token is the same
that was used to obtain the auth code.
* The only time a request is not made over SSL is the redirect with the
auth_code which is very short-lived (30 seconds) and is tied to a verified
redirect URI.
* We enforce that access tokens must be provided using the Authorization
header only (and of course, over SSL).
* We have guidelines saying that all mobile apps must use the native browser
(and not an embedded web UI).

Questions:
========
1. Given the above scenario, what use are refresh tokens?
  - Access tokens can not leak because every request (to resource and authz
server) containing an access token is done over SSL. We control both the
authz and resource servers, so tokens in logs (and other suggested reasons
in the archives) are not an issue.
  - Long-lived refresh tokens and short-lived access tokens are supposed to
provide security due to possible access token leakage... but in our 100%
SSL scenario, if access tokens are able to leak, then so would the client
id, secret and refresh token.
  - Having a long-lived refresh token that can be exchanged for another
access token adds a level of complexity (a second HTTPS request every so
often) and seems to provide no benefit for our case.


2. What is the point of the client secret (in our scenario)?
- We originally were treating the clients as confidential, but after
re-reading the native-application section, it seems we really should treat
them as public (phone apps can be decompiled and the secret discovered).
- The spec says that the authz server should
authenticate confidential clients, but public clients are allowed to just
send their public client id (and no secret).
- The only verification then, is to enforce redirect URI registration and to
validate the redirect URI between authorization and token steps.

So, the question is, assuming that we, one: "enforce redirect-URI
registration" and two: "validate that URI" - why can't we treat all clients
as public and not worry about a secret?
What is the benefit of having confidential clients (and a secret) at all?


Our API source is not available, but the oauth2 server implementation can be
seen here: https://github.com/quizlet/oauth2-php

Regards,
Dave