LinkTaco offers an OAuth 2.0-compatible (RFC 6749) authorization process for access to the GraphQL API. This document explains the specific details of our RFC 6749 implementation and is intended to be accompanied by a reading of the RFC.
Our OAuth 2.0 implementation has the following caveats:
In the use-case of a native application, where the public client type specified in RFC 6749 is preferred, the application must either provide a web server component which completes the confidential authentication process and shares the access token with the application; or the application should ask the user to provide a personal access token, which can be generated at linktaco.com/oauth2/personal. In the latter case, the application should inform the user of the grant string which supports only the minimum access level required to use the application's features.
OAuth 2.0 clients using LinkTaco must specify explicitly the list of features they wish to be granted permission to use.
The format of the scope string, per section 3.3 is a
space-delineated list of grants. Each grant has three components: service,
scope, and access kind; and is formatted as scope:access kind
.
The scope is the specific feature of that service which the grant applies to,
such as "PROFILE". The list of access scopes available for each API is
documented in the GraphQL schema for that API in the enum AccessScope
type.
The access kind is either RO
or RW
; respectively referring to read-only or
read/write access to that scope.
Example: PROFILE:RO LINKS:RW ANALYTICS:RO
The scopes necessary to use each GraphQL resolver are also indicated in the
GraphQL schema with the @access
directive.
The access scopes supported by LinkTaco, and the required scopes to utilize each resolver, are documented in the GraphQL schema.
They can also be requested programmatically by fetching the following URL:
https://api.linktaco.com/query/api-scopes.json
The following scopes are available for use:
OAuth 2.0 clients may be registered at linktaco.com/oauth2/clients. You will be issued a client ID and secret per sections 2.2 & 2.3. The client ID is a UUID, and the secret is 64-byte random string, base64 encoded. It is not necessary to interpret them; they are passed verbatim to our OAuth 2.0 endpoints.
The authorization endpoint (see section 4.1.1) is
https://linktaco.com/oauth2/authorize
. Note that LinkTaco differs from the
specification in that it REQUIRES the scope parameter to be provided; per
section 3.3 LinkTaco interprets the absence of the scope
parameter as an invalid scope and will cause the request to fail.
To start the exchange, direct the user to the following URL:
https://linktaco.com/oauth2/authorize
Provide the following parameters in the query string:
The optional state
field is returned to you after the redirect. One example
use-case of this field is generating a token before directing the user to the
authorization page and validating it after the redirect, to prevent users from
initiating the OAuth flow without you. Most users don't need to worry about
this.
The optional redirect_uri
must match the redirect uri specified in the OAuth
2.0 client configuration.
The authorization code issued is a 32 character hexadecimal string, and it must be used within 5 minutes.
The access token endpoint (see section 4.1.3) is
https://linktaco.com/oauth2/access-token
. The optional redirect_uri
must
match the redirect uri specified in the OAuth 2.0 client configuration. HTTP
Basic authentication is also recommended per section 2.3.1.
Our access token response will always set the token type to "bearer".
There are various ways, in order of complexity and flexibility, of authenticating with the API. Your goal is to obtain an access token, which can be used to authenticate with the API.
The easiest and fastest way to authenticate with LinkTaco is to create a personal access token. This token will have unrestricted access to the API and can be used like a normal access token to authenticate API requests (see Authenticating API requests).
Warning: do not give your personal access tokens to third parties. Any third party which encourages you to give them a personal access token should instead develop an OAuth 2.0 client as described in the next section.
Personal access tokens are suitable for authenticating yourself, but if you intend to provide software that other LinkTaco users can log into, you should create an OAuth client instead. The OAuth 2.0 flow allows end-users to grant your client only the privileges it requires to execute its duties and to revoke this access at any time. This is accomplished through an OAuth 2.0 exchange:
code
parameter.To this end, you need to have an HTTP server running somewhere (localhost
is
suitable for testing) that the user can be redirected to upon consenting to the
permissions you requested. Decide on a URL we can redirect the user to in your
application, and fill out the base redirect URI accordingly.
Upon submitting the form, your client ID and client secret will be shown to you. Record your client secret now. It will not be shown to you again.
API endpoints on LinkTaco generally require an access token valid for a specific scope to be used. This allows you to only request access to the subset of the API that you require. Scopes are written with the following notation(s):
name
name:access
name
is the name of the OAuth 2.0 scope, which is documented alongside the API
resolvers which require it (e.g. getFeed
requires the PROFILE
scope). access
is either RO
or RW
, and may be omitted (default:
RO
).
Scopes sent to the authorize endpoint should be space separated. For instance:
PROFILE:RO LINKS:RW ANALYTICS
Once the user consents, they will be redirected to your configured application
redirect_uri
. We will update your redirect URI with some additional query
string parameters you can use for the next steps:
Possible values for error
:
access_declined
invalid_request
invalid_scope
server_error
Important: the user is able to edit the scopes you've requested before consenting. You must handle the case where the scopes returned when obtaining an access token do not match the scopes requested.
Once your application retrieves the exchange token from the redirect, you can
submit an HTTP POST request to https://linktaco.com/oauth2/access-token
. The
request Content-Type
should be application/x-www-form-urlencoded
and
include the following parameters:
You will receive a response like this:
{
"access_token": "your access token",
"token_type": "bearer",
"expires": 1736201028,
"scope": "PROFILE:RO ANALYTICS:RW",
"refresh_token": "refresh token"
}
The expires
date is in Unix epoch format.
You can now use this token for Authenticating API requests.
You can refresh an access token programmatically to avoid service disruptions. To refresh a token simply follow the same steps in "Obtaining an access token" above. You must:
refresh_token
in the grant_type
parameter.refresh_token
parameter.Upon a successful refresh you will receive the same response json as when obtaining a new token. You should then update your own database with the new access token, refresh token, and expiration date.
On the security tab of your OAuth 2.0 client's dashboard (which can be accessed from the OAuth clients page), you can rotate your client secret, in the event that it is compromised.
On the security tab of your OAuth 2.0 client's dashboard (which can be accessed from the OAuth clients page), you can revoke all issued access tokens at once, in the event some or all of them are compromised. Users will have to repeat the authorization flow.
Authenticating your API request is simple once you have an access token. You
just need to set the Authorization
header to Bearer your-access-token
. For
example:
oauth_token=your oauth token
curl \
--oauth2-bearer "$oauth_token" \
-H 'Content-Type: application/json' \
-d '{"query": "{ version { major, minor, patch } }"}' \
https://api.linktaco.com/query
Our GraphQL setup is heavily based on the SourceHut GraphQL services. As such this document is a modified version of the original SourceHut document.
commit 2aac1348afc29af64b6d24324bd435bffb2881d1 Author: Peter Sanchez <peter@netlandish.com> Date: 2025-02-24T14:03:34-06:00 Fixing anchor name in support doc