IBM Cloud Docs
Working with your IBM Cloudant account

Working with your IBM Cloudant account

Your account is your entry point for the IBM® Cloudant® for IBM Cloud® API. You access your account by using the address prefix https://$ACCOUNT.cloudant.com.

For your IBM Cloudant Dashboard, you always use this address: https://$ACCOUNT.cloudant.com/dashboard.html.

If you don't have an account yet, sign in to IBM Cloudant.

To see whether your IBM Cloudant account is accessible, make a GET against https://$ACCOUNT.cloudant.com. If you misspell your account name, you might get the following error, 503: Service unavailable. You can see the types of authentication that are available in the following list:

IAM authentication

You can perform the following tasks with IAM:

  • Centrally manage access management across IBM Cloud.
  • Allow a user or service to access many different resources by using the same set of credentials (for example, same username and password or IAM API key).
  • IAM API keys can be granted access to account management functions, like creating new databases.

For more information, see Managing access or an overview of IAM.

Authentication

Authentication means proving who you are. You prove your identity by supplying your user credentials for verification.

Basic authentication is similar to showing an ID at a door to be checked every time that you want to enter. Cookie authentication is similar to having a key to the door so that you can let yourself in whenever you want. Within IBM Cloudant, the key is a cookie that is named AuthSession.

When you create or use performance-critical IBM Cloudant applications, cookie authentication has more benefits when compared with Basic authentication. We encourage you to use cookie authentication whenever possible.

Basic authentication

To use Basic authentication, pass your credentials as part of every request. You pass your credentials by adding an Authorization header to the request.

The header includes the authentication scheme (Basic), followed by the BASE64 encoding of a string created by concatenating:

  • Your username
  • The : character
  • Your password

In practice, many application libraries that are used for creating HTTP requests can do this encoding for you.

For more information, see Security scheme on basic authentication.

Authorization

After authenticating, the next test is to decide whether you're allowed to do certain tasks. This decision is called authorization.

When you authenticate with the IBM Cloudant system, it "knows" who you are. The next question is, what tasks are you allowed to do?

You might create a complete list of all the possible tasks that you can do, for each aspect of an IBM Cloudant system, such as a database or a document. Although simple, this approach would require many lengthy lists. Keeping those lists accurate and complete is impractical.

A better approach uses the idea of "roles". The various tasks can be grouped into collections that are typical of some generic roles. For example, the task of creating or deleting a database is characteristic of someone with an administrative role. Similarly, the task of creating or updating a document is characteristic of someone with a "writing" role.

Rather than explicitly listing every task you can do, you're given one or more roles. If you have a role, then you can do all the tasks that are associated with that role.

Roles

The following section applies only to legacy credentials. For more information about using roles with IAM credentials, see IBM Cloudant roles.

IBM Cloudant has a number of roles available. The roles can be assigned to user accounts or API keys.

The three core roles are defined in the following table:

Table 2. Core roles
Role Description
_admin Change security settings, including adding roles.
_reader Read documents from the database.
_writer Create, update, and delete documents (except design documents) in the database.

The _reader and _writer roles are exclusive. If a user has the _writer role, they can't read documents that they create unless they also have the _reader role.

You might want to assign more than one role. For example, a user might need to read from or write to documents within a database, but wouldn't need full administrative control over the database. To fulfill this requirement, the user's account is granted the _reader and _writer roles, but not the _admin role.

A number of "focused" roles are also available. These provide permissions for specific API endpoints. The focused role permissions are similar to the core role permissions, but apply only to the specific API endpoint.

The focused roles are defined in the following table:

Table 3. Focused roles
Role Description API Endpoints
_design Allows create, read, modify, or delete access to design documents. _design, _find, _index
_replicator Allows read access to replicate data from a database, and write access to create checkpoints. _local, _replicate, _replicator
_security Allows read and write access to the /$DATABASE/_security endpoint. _security

The nature of the access that is granted depends on the specific API endpoint. For example, the _design role provides access that allows a user or API key to create, read, modify, or delete design documents. If you grant access this way, the advantage is that you're not required to assign the more widely applicable _reader or _writer roles. This distinction is useful because otherwise the authorized account might read from or write to documents within the database, other than the design documents.

The credentials that you use to log in to the dashboard automatically have the _admin role for all databases you create. Everyone and everything else, including users that you share databases with, and API keys you create, must be given a role explicitly to do corresponding tasks.

The special nobody username applies for anyone or any application that tries to do tasks, but that didn't authenticate with the system. In other words, the nobody username applies to all unauthenticated connection attempts. For example, if an application tries to read data from a database, but didn't identify itself, the task can continue only if the nobody user has the role _reader.

It's possible to grant more powerful roles to an unauthenticated user than to an authenticated user. For example, if the nobody username is intentionally granted _admin, _reader, and _writer roles, but an authenticated user account such as alexone is granted only the _reader role. In this case, it's possible that an unauthenticated user might have a more powerful role than the authenticated alexone user.

It's important to understand that the nobody username is not a way of supplying a default set of permissions. Instead, the nobody username is used to determine permissions for unauthenticated users.

Determining the role to assign

First, determine the role or roles to assign to a user account or API key. It's best to assign a role with the least permissions necessary to do the tasks for that account or API key.

If the tasks are for a specific aspect, such as working with design documents or security settings, then assign a focused role, such as _design or _security.

API keys

The following section applies only to legacy credentials. For more information about using API keys with IAM credentials, see IAM API keys.

Use API keys to enable database access for a person or application, but without creating a new IBM Cloudant account for that person or application. An API key is a randomly generated username and password. The key is given the wanted access permissions for a database.

When a key is generated, and granted the required access permissions, the API key can be used in the same way as a normal user account.

However, API keys aren't the same as normal user accounts. An API key doesn't have access to the dashboard.

An API key is primarily used to enable applications to access a database, with a determined level of access control.

All IBM Cloudant instances that are deployed from the IBM Cloud® Public Germany region are deployed in EU-managed environments. Any IBM Cloudant account or API key that is generated outside an EU-managed environment can't be granted access to an EU-managed IBM Cloudant instance. For more information about IBM Cloudant in an EU-managed environment, see Locations and tenancy.

Creating API keys

An earlier method of generating API keys by issuing the POST command to the https://cloudant.com/api/generate_api_key endpoint is deprecated.

You can create an API key in the following two ways:

  1. Use the dashboard.
  2. Use the IBM Cloudant API to modify the permissions.

No matter what method you choose, remember to record the key name and password. These values are both randomly generated, and can't be retrieved if lost or forgotten.

Using API keys

API keys are typically generated by using an account that has at least one database. It's possible to use the API key with other databases, or even with other accounts.

By default, an API key has no permissions. It must be given permissions explicitly.

After you generate the API key, grant the key access-specific permissions for a specific database by sending a PUT request to https://$ACCOUNT.cloudant.com/_api/v2/db/$DATABASE/_security.

The database isn't required to be in the same account as the account used for generating the API key initially.

To give an existing API key permission to access a database in another account, follow these steps:

  1. Retrieve the existing security permissions for the database.
  2. Add the details of the API key to the database security permissions, along with the roles required.

For an example of this process, see the blog article: Using an IBM Cloudant API key with multiple IBM Cloudant databases and accounts.

Deleting API keys

It's not possible to delete an API key. An API key is always available for use if you know the key and its password. However, the API key is only useful when you assign it to a database, and assign permissions for working with the database.

To "delete" an API key, remove it from the database. All the permissions that were previously assigned to the API key for it to work with that database are then removed.

To remove an API key by using the Dashboard

  1. Click Databases > Permissions.
  2. Hover over the API key that you would like to delete.
  3. Click the "X" that appears when you hover over the API key.

To remove an API key by using the IBM Cloudant API

Use the modifying permissions technique to remove the API key from the list of users with access permission.

This technique works because an API key is similar to a user, and is granted access permissions. By removing the API key from the list of users that have access permissions, you remove the API key from the list of users that have access to the database.

To remove the API key, send an HTTP PUT request to the same _security API endpoint you used to create the API key. This request removes the API key from the list of users with access permission. Provide an updated list of the usernames that have access permission. The updated list must not include the API key.

Using the _users database with IBM Cloudant

The following section applies only to legacy credentials.

You can use the _users database to manage roles in IBM Cloudant.

User documents that are stored in the _users database must be structured and populated to comply with Apache CouchDB requirements.

You can disable the IBM Cloudant authorization checks by setting the couchdb_auth_only:true parameter. To disable IBM Cloudant security, PUT a JSON document to the _security endpoint of the database. For example, https://$ACCOUNT.cloudant.com/$DATABASE/_security.

See the following example that uses HTTP to submit a modification request:

PUT /$DATABASE/_security HTTP/1.1
Content-Type: application/json

See the following example to submit a modification request:

curl -H "Authorization: Bearer $API_BEARER_TOKEN" -X PUT "$SERVICE_URL/products/_security" -H "Content-Type: application/json" --data '{"members": {"names": ["user1", "user2"], "roles": ["developers"]}}'
import com.ibm.cloud.cloudant.v1.Cloudant;
import com.ibm.cloud.cloudant.v1.model.Ok;
import com.ibm.cloud.cloudant.v1.model.PutSecurityOptions;
import com.ibm.cloud.cloudant.v1.model.SecurityObject;

import java.util.Arrays;

Cloudant service = Cloudant.newInstance();

SecurityObject members = new SecurityObject.Builder()
    .names(Arrays.asList("user1", "user2"))
    .roles(Arrays.asList("developers"))
    .build();

PutSecurityOptions securityOptions =
    new PutSecurityOptions.Builder()
        .db("products")
        .members(members)
        .build();

Ok response =
    service.putSecurity(securityOptions).execute()
        .getResult();

System.out.println(response);
const { CloudantV1 } = require('@ibm-cloud/cloudant');

const service = CloudantV1.newInstance({});

const members: CloudantV1.SecurityObject = {
  names: ['user1', 'user2'],
  roles: ['developers']
};

service.putSecurity({
  db: 'products',
  members: members
}).then(response => {
  console.log(response.result);
});
from ibmcloudant.cloudant_v1 import CloudantV1, SecurityObject

service = CloudantV1.new_instance()

members = SecurityObject(
  names=['user1', 'user2'],
  roles=['developers']
)

response = service.put_security(
  db='products',
  members=members
).get_result()

print(response)
putSecurityOptions := service.NewPutSecurityOptions(
  "products",
)
putSecurityOptions.SetMembers(&cloudantv1.SecurityObject{
  Names: []string{"user1", "user2"},
  Roles: []string{"developers"},
})

ok, response, err := service.PutSecurity(putSecurityOptions)
if err != nil {
  panic(err)
}

b, _ := json.MarshalIndent(ok, "", "  ")
fmt.Println(string(b))

The previous Go example requires the following import block:

import (
   "encoding/json"
   "fmt"
   "github.com/IBM/cloudant-go-sdk/cloudantv1"
)

All Go examples require the service object to be initialized. For more information, see the API documentation's Authentication section for examples.

See the following example modification request in JSON format:

{
	"couchdb_auth_only": true,
	"members": {
		"names": ["member"],"roles":[]
	},
	"admins": {
		"names": ["admin"],"roles":[]
	}
}

See the following example response from a modification request:

{
	"ok" : true
}