Initial commit

This commit is contained in:
zhongjin
2020-06-15 10:58:47 +08:00
commit 4f1dfe7564
8590 changed files with 1516878 additions and 0 deletions
@@ -0,0 +1,20 @@
## CARTO Authorization
All requests to CARTO's APIs (Maps, Sql, etc.) require you to authenticate with an API Key.
API Keys identify your project and provide a powerful and flexible primitive for managing access to CARTO's resources like APIs and Datasets.
These API Keys can be provisioned, revoked and regenerated through the [Auth API]({{site.authapi_docs}}/reference/) or the dashboard. You are able to manage authorization through the UI, by [logging on to your CARTO account](https://carto.com) and managing everything in there. Here you have an example of the authorization dashboard in a real CARTO account.
![Authorization dashboard image 1](../img/capture-dashboard-auth.png)
And here you can see the process of creating a new API key, managing its name and resources in terms of APIs and Datasets, including its permissions.
It requires to add a name and grant permission for at least one of these:
* SQL API: you will have to include CREATE datasets or specific permissions on any table.
* MAPS API: you will have to specify SELECT permissions on any table.
* CREATE datasets: allows you to create tables in the user schema by using the SQL API, and also modify or delete the tables previously created with it. It won't allow to modify or delete a table created with a different API key, in that case you'll receive an `Access denied` error.
* LISTING datasets: allows to read the metadata from the existing tables, views and materialized views in the user schema by using the endpoint: `api/v4/datasets`
![Authorization dashboard image 2](../img/capture-auth-new-apikey.png)
**Warning:** Changes to the key permissions are not possible once key is generated.
@@ -0,0 +1,78 @@
## How to send API Keys
A CARTO API Key is physically a token/code of 12+ random alphanumeric characters.
You can pass in the API Key to our APIs either by using the HTTP Basic authentication header or by sending an `api_key` parameter via the query string or request body.
**Tip:** If you use our client library CARTO.js, you only need to follow the authorization section and we will handle API Keys automatically for you.
The examples shown to illustrate the different methods of how to send API Keys use the following parameters:
```
- user: username
- API Key: 1234567890123456789012345678901234567890
- API endpoint: https://username.carto.com/endpoint/
```
### HTTP Basic Authentication
Basic Access Authentication is the simplest technique of handling access control and authorization in a standardized way. It consists essentially of an `HTTP Authorization Basic` header followed by the user credentials (username and password) encoded using base64.
If that looks complicated to you, dont worry. Most client software provide simple mechanisms to use HTTP Basic Authentication, like [curl](https://ec.haxx.se/http-auth.html), [Request](https://github.com/request/request#http-authentication) (JavaScript) and [Requests](http://docs.python-requests.org/en/master/user/authentication/#basic-authentication) (Python).
For requests to CARTOs APIs, take the API Key as the password, and the username as the user who issued that API Key.
#### Examples:
##### Curl
```bash
curl -X GET \
'https://username.carto.com/endpoint/' \
-H 'authorization: Basic dXNlcm5hbWU6MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MA=='
```
##### Request (JavaScript)
```javascript
request.get('https://username.carto.com/endpoint/', {
'auth': {
'user': 'username',
'pass': 1234567890123456789012345678901234567890
}
});
```
##### Requests (Python)
```python
r = requests.get('https://username.carto.com/endpoint/', auth=(username, 1234567890123456789012345678901234567890))
```
### Query string/Request body parameter
Alternatively, you can use an URL query string parameter or a field in the request body. In both cases, the name of the parameter is `api_key`.
#### Examples:
```bash
curl -X GET 'https://username.carto.com/endpoint/?api_key=1234567890123456789012345678901234567890'
```
```bash
curl -X POST \
'https://username.carto.com/endpoint/' \
-H 'content-type: application/json' \
-d '{
"api_key": "1234567890123456789012345678901234567890"
}'
```
If, for some mysterious reason, you submit the API Key with more than one of the available methods, the order of precedence is as follows:
1. HTTP Basic Authentication header
2. URL query string parameter
3. Request body field
Likewise, for security reasons and future-proofing, we recommend that you use that same order when choosing a method for sending the API Key. In other words, favour the use of HTTP Basic Authentication over the URL query string, and try to avoid the body field. We support this method just for backwards compatibility.
@@ -0,0 +1,78 @@
## Types of API Keys
In CARTO, you can find 3 types of API Keys:
- Regular
- Default public
- Master
#### Regular
Regular API Keys are the most common type of API Keys. They provide access to APIs and database tables (AKA datasets) in a granular and flexible manner.
For example one API key can provide access to:
- The SQL API
- The `world_population` dataset with select permission
- The `liked_cities` dataset with select/insert permissions
- Creating new datasets in the user account
- Listing existing datasets in the user account
With this API Key you can:
- Access the SQL API, but not the Maps API.
- Run a `SELECT SQL` query to the `world_population` dataset, but not an `UPDATE`, `DELETE` or `INSERT`.
- Run an `INSERT` to the `liked_cities` dataset, but not to `national_incomes`.
- Run `CREATE TABLE AS...` SQL queries to create new tables in the user account. As the owner of the tables created you'll also be able to `DROP` and `ALTER` the created tables.
- Read metadata (like name or privacy) from `national_incomes`, but not its content.
It's possible to create as many regular API Keys as you want. Moreover, to enforce security, we encourage you to create as many regular API Keys as apps/maps you produce. Since regular API Keys can be independently revoked, you have complete control of the lifecycle of your API credentials.
An important property to keep in mind about regular API Keys is that they are *not editable*. You can not add/delete datasets nor APIs. Its designed this way on purpose for security reasons.
Another important property of Regular API keys is that they inherit all the datasets permissions from the Default Public API Key.
You can see below an example of a real API key as it is displayed in a CARTO account.
![Capture Auth API key section in dashboard](../img/capture-auth-apikey.png)
#### Default Public
Default public are a kind of regular API Keys. They too provide access to APIs and datasets, but for the latter in a read-only way.
Every user has one and only one Default Public API Key. That means that on user creation a Default API Key is issued for that user, and that these type of keys are not revocable/deletable.
For example one Default Public API Key can provide access to
- the SQL API
- the Maps API
- the `world_population` dataset with read permission
- the `liked_cities` dataset with read permission
As you can see, API and read-only selected datasets access are possible.
At the beginning of this authentication section we stated that all API requests require an API Key. Well, we lied a little bit. If none is provided, the Default Public API Key is used as a fall back.
**Warning:** This is done for backwards compatibility reasons. Dont expect this behaviour to be maintained in the long term, it can be deprecated.
Get used to always send an API Key, even if its the Default Public.
A cosmetic difference compared to the other API Key types is the code/token that identifies these API Keys, its just: _default_public_. Its a simple human-readable constant string, no randoms involved.
#### Master
Master keys are a very special kind of API Keys. As it happens with the Default Public type, every user has one and only one Master non revocable API Key.
The special thing about Master API Keys is that they grant access to EVERYTHING: APIs and datasets (select/insert/create/delete). Additionally, a Master API Key is required to access most of the Auth API endpoints.
Your Master API key carries many privileges, so be sure to keep it secret. Do not share it in publicly accessible areas such as GitHub or client-side code.
Below you have an example of a master API key.
![Capture Master Auth API key section in dashboard](../img/capture-auth-apikey-master.png)
**Tip:** If you think is has been compromised, regenerate it immediately.
Actually, you should use Master API Keys sparingly. Try to limit its direct use only to interact programmatically with the [Auth API]({{site.authapi_docs}}/reference/). Issue and use regular API Keys for the rest of use cases.
@@ -0,0 +1,9 @@
## General Considerations
- Regenerate a regular/master API Key if you suspect it has being compromised. A regenerated API Key grants the same permissions as before, but has a new code/token. Maps/apps using a regenerated API Key must be updated to adapt to that change, otherwise they will stop working.
- Send always an API Key in your API requests
- Issue a new regular API Key per map/app. Try to avoid sharing keys between maps/apps
- Grant the least amount of necessary permissions per API Key
- Use the Master API Key sparingly
- Keep your Master API Key secret!
- Do not overuse the Default Public API Key. Its meant for obviously public Datasets.
@@ -0,0 +1,45 @@
## Authorization for CARTO views
With the [CARTO Auth API](https://carto.com/developers/auth-api/), it is possible to create API Keys not only for tables in CARTO (aka datasets), but also for Views in CARTO.
CARTO use PostgreSQL as the database to store your datasets, so you can create a View in CARTO in the same way that it is created in PostgreSQL. We would recommend checking [this section](https://www.postgresql.org/docs/9.5/static/tutorial-views.html) of the PostgreSQL documentation if you want to learn more about how Views are created in PostgreSQL.
What is the advantage of using a View with the CARTO Auth API? Well, in order to answer that question, let's assume that you have a dataset in CARTO and you want to restrict partial information of your dataset when publishing a map or using the SQL API. For example, you might have a dataset named `clients` with [private privacy](https://carto.com/learn/guides/publish-share/privacy-settings-for-protecting-maps-and-data/) and you want to build a map with clients of New York area only, so you can create a View as it is done in the next block of code:
```sql
CREATE VIEW clients_nyc AS (
SELECT * FROM clients WHERE area = 'NY'
);
```
Now, you would need to use the Auth API in order to create the API Key for the View with a payload that sets the permissions of the new API Key that will be created. In this example, we are giving read-only or select permission to our View so it can only be available when using the API key with the [CARTO Maps API](https://carto.com/developers/maps-api/) or [CARTO.js](https://carto.com/developers/carto-js/).
```json
{
"name": "Clients-NYC",
"grants": [
{
"type": "apis",
"apis": [
"maps"
]
},
{
"type": "database",
"tables": [
{
"schema": "public",
"name": "clients_nyc",
"permissions": [
"select"
]
}
]
}
]
}
```
If you try to access to the data of this View using the [CARTO SQL API](https://carto.com/developers/sql-api/), you will receive a forbidden error, because this API Key do not have permissions to be accessed using the CARTO SQL API.
So, by creating API Keys for the Views in CARTO using the Auth API, we can display the information partial information that we want and at the same time, keeping our data private.
Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

@@ -0,0 +1,621 @@
openapi: 3.0.0
info:
title: Auth API
description: >
# Introduction
This API allows you to manage API keys. API keys are the fundamental
building block of CARTO's authorization system. See this this guide for more
information.
This API accepts and returns JSON.
API base endpoint is `https://<your_username>.carto.com/api/v3/api_keys` or `https://<org_name>.carto.com/u/<your_username/api/v3/api_keys` in case you are using a user belonging to an organization.
# Authorization
There are three different API Keys that provide with different access privileges:
1. `default`: This API provides access to all public objects. It cannot be removed.
1. `master`: Using this API Key you will have full access and will be able to create/manage `regular` API Keys. It cannot be removed. You should keep its token safe and use it only when strictly necessary.
1. `regular`: This API Keys can be created with custom access privileges and can also be removed.
# API Key format
Every API Key consists on four main parts:
1. **name**: You will choose it when creating the API Key and it will be used for indexing your API Keys.
1. **type**: As mentioned before, there are three type of API Keys: `default`, `master` and `regular` providing different levels of access.
1. **token**: It will be used for authenticating your requests.
1. **grants**: Describes which APIs this API Key provides access to and to which tables. It consists on an array of two JSON objects. This object's `type` attribute can be `apis`, `database` or `dataservices`:
- `apis`: Describes which APIs does this API Key provide access to through `apis` attribute:
```{
{
"type": "apis",
"apis": [
"sql",
"maps"
]
}
```
- `database`: Describes to which tables and schemas and which privileges on them this API Key grants access to through `tables`, `schemas` and `table_metadata` attributes.
You can grant read (`select`) or write (`insert`, `update`, `delete`) permissions on tables.
For the case of `schemas`, once granted the `create` permission on a schema, you'll be able to run SQL queries such as `CREATE TABLE AS...`, `CREATE VIEW AS...` etc. to create entities on it.
Also, you can allow to list all tables metadata (like name or privacy) with the `table_metadata` attribute.
```{
{
"type": "database",
"tables": [
{
"schema": "public",
"name": "my_table",
"permissions": [
"insert",
"select",
"update"
]
}
],
"schemas": [
{
"name": "public",
"permissions": [
"create"
]
}
],
"table_metadata" : []
}
```
- `dataservices`: Describes to which data services this API Key grants access to though `services` attribute:
```{
{
"type": "dataservices",
"services": [
"geocoding",
"routing",
"isolines",
"observatory"
]
}
```
# Authentication
In order to authenticate your requests to the API, they need to include a `Basic` `Authentication` header, where the `username` would be your username and the `password` would be your API Key's token. This authentication method will be valid across all CARTO components (Auth API, Maps API, SQL API). You can build your own `Authorization` header as follows:
```
"Basic #{Base64.strict_encode64(username + ':' + api_key.token)}"
```
**Important:** The API key you provide to access Auth API must be of type
`master`.
version: 0.0.1
contact:
name: Have you found an error? Github issues
url: 'https://github.com/CartoDB/cartodb/issues/new'
servers:
- url: 'https://{user}.carto.com/api/v3'
description: Production server (uses live data)
variables:
domain:
default: carto.com
description: 'If on premise, change it to your domain'
user:
default: username
description: Your username
paths:
/api_keys:
get:
summary: List API keys
description: Returns the API keys list.
tags:
- API Keys
operationId: getApiKeys
parameters:
- in: query
name: per_page
schema:
type: integer
description: Limits number of API Keys listed
required: false
- in: query
name: page
schema:
type: integer
description: Defines what page to fetch
required: false
- in: query
name: order
schema:
type: string
description: Its used to define the critera by which API Keys are listed. It can be any of the attributes
required: false
responses:
'200':
description: Ok
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/ApiKeys'
'401':
$ref: '#/components/responses/Unauthorized'
security:
- ApiKeyHTTPBasicAuth: []
- ApiKeyQueryParam: []
post:
summary: Create API key
description: >-
Creates a `regular` API key. `master` and `default_public` API Keys are automatically generated on
user's creation.
tags:
- API Keys
operationId: createApiKey
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ApiKeyCreation'
responses:
'201':
description: Created
content:
application/json:
schema:
$ref: '#/components/schemas/ApiKey'
'401':
$ref: '#/components/responses/Unauthorized'
'422':
$ref: '#/components/responses/BadInput'
security:
- ApiKeyHTTPBasicAuth: []
- ApiKeyQueryParam: []
'/api_keys/{name}':
parameters:
- $ref: '#/components/parameters/apiKeyName'
get:
summary: Get API key
description: >-
Returns an API key based on its `name`.
tags:
- API Keys
operationId: getApiKeyById
responses:
'200':
description: Ok
content:
application/json:
schema:
$ref: '#/components/schemas/ApiKey'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
security:
- ApiKeyHTTPBasicAuth: []
- ApiKeyQueryParam: []
delete:
summary: Delete API key
description: >-
Deletes an API key based on it's `name`. Only `regular` API keys can be
deleted.
tags:
- API Keys
operationId: deleteApiKeyById
responses:
'200':
description: The resource was deleted successfully.
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
security:
- ApiKeyHTTPBasicAuth: []
- ApiKeyQueryParam: []
x-code-samples:
'/api_keys/{name}/token/regenerate':
parameters:
- $ref: '#/components/parameters/apiKeyName'
post:
summary: Regenerate API key token
description: Regenerates the API key token. The rest of the fields remain the same.
tags:
- API Keys
operationId: regenerateApiKeyById
responses:
'200':
description: Ok
content:
application/json:
schema:
$ref: '#/components/schemas/ApiKey'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
security:
- ApiKeyHTTPBasicAuth: []
- ApiKeyQueryParam: []
x-code-samples:
components:
schemas:
ApiKeys:
type: object
properties:
total:
type: integer
description: Total number of API Keys
count:
type: integer
description: Number of returned API Keys
result:
type: array
items:
$ref: '#/components/schemas/ApiKey'
_links:
type: object
properties:
first:
$ref: '#/components/schemas/Links'
description: Link to the first page
prev:
$ref: '#/components/schemas/Links'
description: Link to the previous page
next:
$ref: '#/components/schemas/Links'
description: Link to the next page
last:
$ref: '#/components/schemas/Links'
description: Link to the last page
example:
total: 3
count: 3
result:
- name: Master
user:
username: amartin
type: master
token: slxIYwIDyEGGS2W9W-uEKw
grants:
- type: apis
apis:
- sql
- maps
- type: database
tables: []
schemas: []
table_metadata: []
- type: dataservices
services:
- geocoding
- routing
- isolines
- observatory
created_at: '2018-02-08 14:24:41 +0000'
updated_at: '2018-02-08 14:24:41 +0000'
_links:
self: 'https://carto.com/api/v3/api_keys/Master'
- name: MyTableApi
user:
username: amartin
type: regular
token: moLv8B-kotcjUL-uxMhbGg
grants:
- type: apis
apis:
- maps
- type: database
tables:
- schema: public
name: my_table
permissions:
- insert
- select
- update
schemas:
- name: public
permissions:
- create
table_metadata: []
- type: dataservices
services:
- geocoding
- observatory
created_at: '2018-02-14 13:23:12 +0000'
updated_at: '2018-02-14 13:23:12 +0000'
_links:
self: 'https://carto.com/api/v3/api_keys/MyTableApi'
- name: Default public
user:
username: amartin
type: default
token: default_public
grants:
- type: apis
apis:
- sql
- maps
- type: database
tables: []
schemas: []
created_at: '2018-02-15 13:50:36 +0000'
updated_at: '2018-02-15 13:50:36 +0000'
_links:
self: 'https://carto.com/api/v3/api_keys/Default%20public'
_links:
first:
href: 'https://carto.com/api/v3/api_keys?order=updated_at&page=1&per_page=20'
last:
href: 'https://carto.com/api/v3/api_keys?order=updated_at&page=1&per_page=20'
ApiKey:
allOf:
- type: object
properties:
name:
type: string
user:
properties:
username:
type: string
type:
$ref: '#/components/schemas/ApiKeysTypes'
token:
type: string
grants:
type: array
items:
oneOf:
- $ref: '#/components/schemas/ApisGrant'
- $ref: '#/components/schemas/GrantDatabase'
- $ref: '#/components/schemas/GrantDataservices'
_links:
type: object
properties:
self:
$ref: '#/components/schemas/Links'
description: Link to the resource
- $ref: '#/components/schemas/Timestamps'
required:
- name
- type
- grants
example:
name: MyTableApi
user:
username: amartin
type: regular
token: moLv8B-kotcjUL-uxMhbGg
grants:
- type: apis
apis:
- maps
- type: database
tables:
- schema: public
name: my_table
permissions:
- insert
- select
- update
schemas:
- name: public
permissions:
- create
table_metadata: []
- type: dataservices
services:
- geocoding
- observatory
created_at: '2018-02-14 13:23:12 +0000'
updated_at: '2018-02-14 13:23:12 +0000'
_links:
self:
href: 'http://amartin.carto.com/api/v3/api_keys/MyTableApi'
ApiKeyCreation:
type: object
properties:
name:
type: string
description: For identifying your API Key
grants:
type: array
items:
oneOf:
- $ref: '#/components/schemas/GrantDatabase'
- $ref: '#/components/schemas/ApisGrant'
- $ref: '#/components/schemas/GrantDataservices'
discriminator:
propertyName: type
required:
- name
- grants
example:
name: MyTableApi
grants:
- type: apis
apis:
- maps
- type: database
tables:
- schema: public
name: my_table
permissions:
- select
- update
- insert
schemas:
- name: public
permissions:
- create
table_metadata: []
- type: dataservices
services:
- geocoding
- observatory
GrantDataservices:
type: object
properties:
type:
type: string
enum:
- dataservices
services:
type: array
items:
$ref: '#/components/schemas/Dataservices'
uniqueItems: true
required:
- type
- services
Dataservices:
type: string
enum:
- geocoding
- routing
- isolines
- observatory
GrantDatabase:
type: object
properties:
type:
type: string
enum:
- database
tables:
type: array
items:
$ref: '#/components/schemas/TableGrant'
schemas:
type: array
items:
$ref: '#/components/schemas/SchemaGrant'
table_metadata:
type: array
required:
- type
TableGrant:
type: object
properties:
name:
type: string
schema:
type: string
permissions:
type: array
items:
type: string
enum:
- select
- insert
- update
- delete
uniqueItems: true
required:
- name
- schema
- permissions
SchemaGrant:
type: object
properties:
name:
type: string
permissions:
type: array
items:
type: string
enum:
- create
uniqueItems: true
required:
- name
- permissions
ApisGrant:
type: object
properties:
type:
type: string
enum:
- apis
apis:
type: array
items:
$ref: '#/components/schemas/Apis'
uniqueItems: true
required:
- type
- apis
Apis:
type: string
enum:
- sql
- maps
ApiKeysTypes:
type: string
enum:
- master
- default
- regular
Timestamps:
type: object
properties:
createdAt:
type: string
format: date-time
updatedAt:
type: string
format: date-time
Links:
type: object
properties:
href:
type: string
format: url
description: link to the resource
securitySchemes:
ApiKeyHTTPBasicAuth:
type: http
scheme: basic
ApiKeyQueryParam:
type: apiKey
in: header
name: api_key
parameters:
apiKeyName:
in: path
name: name
required: true
schema:
type: string
description: the API key `name`
responses:
NotFound:
description: The specified resource was not found
Unauthorized:
description: Unauthorized. Wrong or no authentication provided.
Forbidden:
description: Forbidden. The API key does not authorize this request.
BadInput:
description: Request's parameters error
@@ -0,0 +1,36 @@
## Support Options
Feeling stuck? There are many ways to find help.
* Ask a question on [GIS StackExchange](https://gis.stackexchange.com/questions/tagged/carto) using the `CARTO` tag.
* [Report an issue](https://github.com/CartoDB/cartodb/issues) in Github.
* Engine Plan customers have additional access to enterprise-level support through CARTO's support representatives.
If you just want to describe an issue or share an idea, just <a class="typeform-share" href="https://cartohq.typeform.com/to/mH6RRl" data-mode="popup" target="_blank"> send your feedback</a>
### Issues on Github
If you think you may have found a bug, or if you have a feature request that you would like to share with the Auth API team, please [open an issue](https://github.com/CartoDB/cartodb/issues/new).
Before opening an issue, review the [contributing guidelines](https://github.com/CartoDB/cartodb/blob/master/CONTRIBUTING.md).
### Community support on GIS Stack Exchange
GIS Stack Exchange is the most popular community in the geospatial industry. This is a collaboratively-edited question and answer site for geospatial programmers and technicians. It is a fantastic resource for asking technical questions about developing and maintaining your application.
When posting a new question, please consider the following:
* Read the GIS Stack Exchange [help](https://gis.stackexchange.com/help) and [how to ask](https://gis.stackexchange.com/help/how-to-ask) pages for guidelines and tips about posting questions.
* Be very clear about your question in the subject. A clear explanation helps those trying to answer your question, as well as those who may be looking for information in the future.
* Be informative in your post. Details, code snippets, logs, screenshots, etc. help others to understand your problem.
* Use code that demonstrates the problem. It is very hard to debug errors without sample code to reproduce the problem.
### Engine Plan Customers
Engine Plan customers have additional support options beyond general community support. As per your account Terms of Service, you have access to enterprise-level support through CARTO's support representatives available at [enterprise-support@carto.com](mailto:enterprise-support@carto.com)
In order to speed up the resolution of your issue, provide as much information as possible (even if it is a link from community support). This allows our engineers to investigate your problem as soon as possible.
If you are not yet CARTO customer, browse our [plans & pricing](https://carto.com/pricing/) and find the right plan for you.
@@ -0,0 +1,36 @@
## Contribute
CARTO platform is an open-source ecosystem. You can read about the [fundamentals]({{site.fundamental_docs}}/components/) of CARTO architecture and its components.
We are more than happy to receive your contributions to the code and the documentation as well.
## Filling a ticket
If you want to open a new issue in our repository, please follow these instructions:
1. Descriptive title.
2. Write a good description, it always helps.
3. Specify the steps to reproduce the problem.
4. Try to add an example showing the problem.
## Contributing code
Best part of open source, collaborate in Auth API code!. We like hearing from you, so if you have any bug fixed, or a new feature ready to be merged, those are the steps you should follow:
1. Fork the repository.
2. Create a new branch in your forked repository.
3. Commit your changes. Add new tests if it is necessary.
4. Open a pull request.
5. Any of the maintainers will take a look.
6. If everything works, it will merged and released \o/.
If you want more detailed information, this [GitHub guide](https://guides.github.com/activities/contributing-to-open-source/) is a must.
## Completing documentation
Auth API documentation is located in ```docs/```. That folder is the content that appears in the [Developer Center](http://carto.com/developers/auth-api/). Just follow the instructions described in [contributing code](#contributing-code) and after accepting your pull request, we will make it appear online :).
**Tip:** A convenient, easy way of proposing changes in documentation is by using the GitHub editor directly on the web. You can easily create a branch with your changes and make a PR from there.
## Submitting contributions
You will need to sign a Contributor License Agreement (CLA) before making a submission. [Learn more here](https://carto.com/contributions).