Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
320 changes: 289 additions & 31 deletions AuthVO.tex
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
\input tthdefs
\input gitmeta
\usepackage[textsize=small,textwidth=3.8cm,backgroundcolor=yellow]{todonotes}
\newcommand{\subsubsubsection}[1]{\paragraph{#1}\mbox{}\\}
\setcounter{secnumdepth}{4}
\setcounter{tocdepth}{4}

\title{Authentication in the Virtual Observatory}

Expand All @@ -13,6 +16,7 @@
\author{Sara Bertocco}
\author{Patrick Dowler}
\author{Brian Major}
\author{Jesus Salgado}

\editor{Mark Taylor}

Expand Down Expand Up @@ -149,7 +153,7 @@ \section{Introduction}\label{sec:intro}
authentication frameworks to any ``VO-sanctioned'' technology,
but by implementing the proposals here they can become usable
in a broader range of scenarios.
VO services however are not required to use any of the
VO services however are not required to use any of the
mechanisms proposed in this document; if they can establish the
client interoperability they require using other mechanisms, or
a combination of VO and other mechansisms, they are free to do so.
Expand Down Expand Up @@ -232,7 +236,7 @@ \subsection{Terminology}

\section{Challenge and Response}

The standard way to negotiate authentication over HTTP is using
The standard way to negotiate authentication over HTTP is using
authentication challenges supplied in HTTP responses.

\subsection{Challenge/Response Framework}
Expand All @@ -246,7 +250,7 @@ \subsection{Challenge/Response Framework}
the basics are outlined here:
% 401, 403, WWW-Authenticate, maybe Authorization.
\begin{itemize}
\item An HTTP response may include one or more
\item An HTTP response may include one or more
\header{WWW-Authenticate} headers
to indicate that authentication is possible.
The content of these headers is one or more {\em challenges},
Expand Down Expand Up @@ -307,7 +311,11 @@ \subsection{Authentication Schemes in the VO}
but the challenge provides no information about how to acquire
such a token which means it is not suitable for clients lacking
prior knowledge about the target service, as described in
Section~\ref{sec:intro}.
Section~\ref{sec:intro}. In order to allow those connections, the
{\em bearer token} response should provide the service configuration
metadata, usually contained in the \verb|discovery_url|.
See \ref{sec:ivoa-bearer}.


Other methods of authentication over HTTP also exist
and are used by VO services,
Expand All @@ -333,7 +341,7 @@ \section{Authentication Schemes}\label{sec:authschemes}
this is communicated by the scheme-specific parameters
\end{enumerate}
Acquiring a permit (such as a cookie, certificate or token)
typically requires supplying credentials known to the user
typically requires supplying credentials known to the user
(such as a username and password) in a particular way to a particular
endpoint.
Common parameters describing this activity are given in
Expand Down Expand Up @@ -504,6 +512,76 @@ \subsubsection{\mbox{\tt ivoa\_x509}}\label{sec:ivoa-x509}
There is an example in Section~\ref{sec:x509-example}.


\subsubsection{\mbox{\tt ivoa\_bearer}}\label{sec:ivoa-bearer}

The \verb|ivoa_bearer| authentication scheme enables Virtual Observatory (VO) services to request Bearer tokens
for secure access control. This approach is aligned with OAuth 2.0 \citep{rfc6749} and OpenID Connect,
offering a standards-compliant and interoperable solution for clients and services.

This scheme supports authentication for headless clients (e.g., command-line tools or scripts) via the Device Authorization Flow \citep{rfc8628}, enabling login through a secondary browser-enabled device.

It also supports token expiry and renewal via refresh tokens, and integrates with OAuth2-compatible infrastructures such as Keycloak-based IAM services.

\begin{description}
\item{{Scheme name:} \verb|ivoa_bearer|}
\item{\textbf{Parameters:}
\begin{itemize}
\item \verb|discovery_url| (required): URL to a discovery document following RFC 8414, providing metadata such as supported grant types and endpoints.
\item \verb|error| (optional): OAuth 2.0-compatible error code, e.g., \verb|invalid_request|, \verb|invalid_token|, or \verb|expired_token|.
\item \verb|error_description| (optional): Human-readable explanation of the error condition.
\end{itemize}}
\end{description}

When a protected resource is accessed without valid authentication, the service responds with:

\begin{verbatim}
HTTP/1.1 401 Unauthorized
WWW-Authenticate: ivoa_bearer \
discovery_url="https://auth.example.org/.well-known/openid-configuration", \
error="missing_token", \
error_description="Authentication required"
\end{verbatim}

The \verb|discovery_url| MUST point to a document conforming to RFC~8414 (OAuth
2.0 Authorization Server Metadata) or OpenID Connect Discovery. It provides the
necessary metadata for client configuration, including:

\begin{itemize}
\item \verb|token_endpoint| — URL to obtain access and refresh tokens.
\item \verb|authorization_endpoint| — URL to initiate browser-based login.
\item \verb|device_authorization_endpoint| — URL to initiate a device
code login for CLI tools.
\item \verb|registration_endpoint| — URL for Dynamic Client Registration
(RFC~7591).
\item \verb|grant_types_supported| — List of supported grant types.
\item \verb|scopes_supported| — List of supported scopes.
\end{itemize}

Possible error codes are standardised on oAuth. A typical list of possible codes can
be found in Table \ref{table:oAuthCodes}.
\begin{table}[]
\centering
\begin{tabular}{ll}
\textbf{Error Code} & \textbf{Description} \\
\verb|invalid_request| & {Request is missing required parameters or malformed.} \\
\verb|unauthorized_client| & {The client is not allowed to use this grant type.} \\
\verb|access_denied| & {The resource owner denied the request.} \\
\verb|unsupported_response_type| & {Response type is not supported by the server.} \\
\verb|invalid_scope| & {The requested scope is invalid or unknown.} \\
\verb|invalid_token| & {The token is expired, malformed, or invalid.} \\
\verb|expired_token| & {The token has expired and must be refreshed.} \\
\end{tabular}
\caption{Standard OAuth 2.0 Error Codes (RFC 6749)}
\label{table:oAuthCodes}
\end{table}

If a client does not already have a \verb|client_id|, it MUST obtain one via
Dynamic Client Registration as described in RFC~7591. The URL of the
registration endpoint is given in the \verb|registration_endpoint| field of
the discovery document. Clients MUST NOT assume this value and MUST always
obtain it from the advertised discovery metadata. See
\ref{sec:ivoa-bearer-flow} for flow and security details.

\subsection{Common Challenge Parameters for VO Schemes}
\label{sec:common-params}

Expand Down Expand Up @@ -555,32 +633,6 @@ \subsubsection{\mbox{\tt standard\_id}}
(a few) deployed services, so it could be painful to change them.
}


\subsection{Bearer Tokens}

Bearer Tokens form the permit for
the OAuth2 authorization framework,
% Terminology: it's called an "Authorization Framework"
% in the title of \rfc{6749} and \rfc{6750}.
which is used by a number of VO data providers.
A bearer token is an opaque string;
in order to use one, the client simply presents the token
following the keyword ``{\tt Bearer}''
in an \header{Authorization} HTTP request header,
as described by \rfc{6750}.

Various methods of token acquisition are defined by OAuth2 and
associated standards, but at time of writing it's not clear which if
any of these are suitable for use by clients lacking prior knowledge
of the services for which they are intended,
and no standard scoping mechanisms seem to be defined.

This document does not therefore currently recommend any way in
which non-browser VO clients can use Bearer Tokens,
but it is hoped that progress will be made on this in future.



\section{Challenge/Response Use in the VO}
\label{sec:cr-use}

Expand Down Expand Up @@ -948,9 +1000,215 @@ \subsection{Mandatory authentication with certificates}
</uws:jobs>
\end{verbatim}
}
\subsection{Authentication Flow and Security Checks using Tokens}
\label{sec:ivoa-bearer-flow}

Command-line tools, batch scripts, or other headless clients often lack
access to a browser, making typical OAuth flows unsuitable. The Device
Authorization Grant (RFC~8628) enables these clients to initiate an
authentication process where the user completes login on a separate
device.

This section defines a unified flow including protocol steps and
mandatory security checks for both clients and services.

\subsubsection{Step 1: Access Protected Resource}

A client attempts to access a protected resource without credentials:

\begin{verbatim}
GET /vo-resource
\end{verbatim}

The service MUST respond with an authentication challenge using HTTP
(RFC~7235) and Bearer token semantics (RFC~6750):

\begin{verbatim}
HTTP/1.1 401 Unauthorized
WWW-Authenticate: ivoa_bearer
error="invalid_request",
error_description="Missing access token",
discovery_url="https://auth.example.org/.well-known/openid-configuration"
\end{verbatim}

The client MUST parse the challenge and extract the
\texttt{discovery\_url}. The client MUST NOT proceed without a valid
\texttt{discovery\_url}.

\subsubsection{Step 2: Retrieve and Validate Discovery Document}

The client retrieves the discovery document (RFC~8414 or OpenID Connect Discovery):

\begin{verbatim}
GET https://auth.example.org/.well-known/openid-configuration
\end{verbatim}

\begin{verbatim}
{
"issuer": "https://auth.example.org",
"token_endpoint": "https://auth.example.org/oauth/token",
"device_authorization_endpoint":
"https://auth.example.org/oauth/device",
"registration_endpoint":
"https://auth.example.org/oauth/register"
}
\end{verbatim}

The client MUST:
\begin{itemize}
\item validate that the document is retrieved via HTTPS,
\item extract required endpoints,
\item verify that the \texttt{issuer} matches the issuer returned in
subsequent token responses (RFC~9207).
\end{itemize}

\textit{Note: The use of RFC~9207 (issuer identification in token
responses) is optional, as it is not universally implemented. If
present, it MUST be validated.}

\subsubsection{Step 3: Dynamic Client Registration (Optional)}

If a \texttt{registration\_endpoint} is provided, the client MUST register
dynamically (RFC~7591):

\begin{verbatim}
POST https://auth.example.org/oauth/register
{
"client_name": "VO CLI Tool",
"grant_types": [
"urn:ietf:params:oauth:grant-type:device_code"
]
}
\end{verbatim}

\begin{verbatim}
{ "client_id": "my-client-id-123" }
\end{verbatim}

The client MUST include the obtained \texttt{client\_id} in subsequent
requests. Dynamically registered clients MUST be treated as public
clients.

\subsubsection{Step 4: Request Device Code}

The client initiates the device authorization flow (RFC~8628):

\begin{verbatim}
POST https://auth.example.org/oauth/device
client_id=my-client-id&scope=openid profile
\end{verbatim}

The response includes:

\begin{verbatim}
{
"device_code": "abc123",
"user_code": "ABC-123",
"verification_uri": "https://auth.example.org/activate",
"verification_uri_complete":
"https://auth.example.org/activate?user_code=ABC-123"
}
\end{verbatim}

\subsubsection{Step 5: User Authentication}

The client MUST instruct the user to authenticate:

\begin{verbatim}
Please open https://auth.example.org/activate
and enter the code: ABC-123
\end{verbatim}

\textbf{Security Warning:} The client SHOULD clearly indicate the service
requesting authentication and the issuer being used, to prevent phishing
or token exfiltration attacks.

\subsubsection{Step 6: Poll Token Endpoint with Resource Indicator}

The client polls the token endpoint (RFC~6749, RFC~8628) and MAY include
a resource indicator (RFC~8707) to request a token scoped to a specific
service:

\begin{verbatim}
POST https://auth.example.org/oauth/token
grant_type=urn:ietf:params:oauth:grant-type:device_code
device_code=abc123
client_id=my-client-id
resource=https://data.example.org
\end{verbatim}

The \texttt{resource} parameter indicates the intended audience of the
token. If supported, the Authorization Server will issue a token bound
to that resource.

\textit{Note: The use of RFC~8707 (Resource Indicators) is optional, as
it is not universally implemented. If supported, clients SHOULD use it
to restrict token usage to the intended service.}

The response contains:

\begin{verbatim}
{
"access_token": "SlAV32hkKG",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "xyz456"
}
\end{verbatim}

The client MUST validate:
\begin{itemize}
\item the presence of an access token,
\item the token type is \texttt{Bearer} (RFC~6750),
\item the issuer if provided (RFC~9207, optional).
\end{itemize}

\subsubsection{Step 7: Access Protected Resource with Token}

The client accesses the resource:

\begin{verbatim}
GET /vo-resource
Authorization: Bearer SlAV32hkKG
\end{verbatim}

The service MUST validate the token:
\begin{itemize}
\item verify signature if JWT-based (RFC~9068),
\item check expiration,
\item verify issuer,
\item verify audience if present (e.g. matching the requested
\texttt{resource}, RFC~8707).
\end{itemize}

\textit{Note: Audience validation (RFC~8707) is optional but strongly
recommended when supported.}

If validation fails, the service MUST reject the request.

\subsubsection{Step 8: Token Refresh (Optional)}

For long-running processes, the client MAY refresh the token (RFC~6749):

\begin{verbatim}
POST https://auth.example.org/oauth/token
grant_type=refresh_token
refresh_token=xyz456
client_id=my-client-id
\end{verbatim}

Refresh tokens MUST be stored securely, as they provide persistent
access.

\subsubsection{Security Considerations}

\begin{itemize}
\item Clients MUST NOT blindly trust discovery metadata.
\item Services MUST validate token integrity and issuer.
\item Clients MUST NOT reuse tokens across unrelated services.
\item Implementations SHOULD restrict tokens to specific resources when
supported.
\end{itemize}
\appendix
\section{Changes from Previous Versions}

Expand Down
Loading
Loading