Proteja as contas de usuário com a Proteção entre contas

Se o app permite que os usuários façam login nas próprias contas usando o Google, é possível melhorar a segurança das contas compartilhadas detectando e respondendo às notificações de eventos de segurança fornecidas pelo serviço de Proteção entre contas.

Essas notificações alertam sobre grandes mudanças nas Contas do Google dos seus usuários, que muitas vezes também podem ter implicações de segurança para as contas com seu app. Por exemplo, se a Conta do Google de um usuário for invadida, isso pode comprometer a conta do usuário com seu app por meio da recuperação de conta de e-mail ou do uso de logon único.

Para ajudar a reduzir o potencial de risco desses eventos, o Google envia seus objetos de serviço chamados tokens de evento de segurança. Esses tokens expõem pouquíssimas informações, apenas o tipo de evento de segurança e quando ele ocorreu, além do identificador do usuário afetado, mas você pode usá-los para tomar as medidas apropriadas em resposta. Por exemplo, se a Conta do Google de um usuário for comprometida, você poderá desativar temporariamente o recurso Fazer login com o Google para esse usuário e impedir que os e-mails de recuperação de conta sejam enviados para o endereço do Gmail dele.

A Proteção entre contas é baseada no padrão RISC, desenvolvido na OpenID Foundation.

Visão geral

Para usar a Proteção entre contas com seu app ou serviço, é necessário concluir as tarefas a seguir:

  1. Configure seu projeto no API Console.

  2. Crie um endpoint de receptor de eventos, que vai receber tokens de eventos de segurança. Esse endpoint é responsável por validar os tokens recebidos e, em seguida, responder a eventos de segurança da maneira que você escolher.

  3. Registre seu endpoint no Google para começar a receber tokens de eventos de segurança.

Pré-requisitos

Você só recebe tokens de eventos de segurança para os usuários do Google que concederam ao seu serviço permissão para acessar as informações do perfil ou os endereços de e-mail deles. Você recebe essa permissão solicitando os escopos profile ou email. Os SDKs Fazer login com o Google mais recentes ou os SDKs legados do Login do Google solicitam esses escopos por padrão, mas se você não usa as configurações padrão ou acessa o endpoint do OpenID Connect do Google diretamente, verifique se está solicitando pelo menos um desses escopos.

Configurar um projeto no API Console

Antes de começar a receber tokens de eventos de segurança, crie uma conta de serviço e ative a API RISC no seu projetoAPI Console . Use o mesmo projetoAPI Console utilizado para acessar os Serviços do Google, como o Login do Google, no seu app.

Para criar a conta de serviço:

  1. Abra o API Console Credentials page. Quando solicitado, escolha o projetoAPI Consoleusado para acessar os Serviços do Google no seu app.

  2. Clique em Criar credenciais > Conta de serviço.

  3. Crie uma nova conta de serviço com o papel Administrador de configuração RISC (roles/riscconfigs.admin) seguindo estas instruções.

  4. Crie uma chave para a conta de serviço recém-criada. Escolha o tipo de chave JSON e clique em Criar. Quando a chave for criada, você vai fazer o download de um arquivo JSON que contém as credenciais da sua conta de serviço. Mantenha esse arquivo em um lugar seguro, mas que também possa ser acessado pelo endpoint do receptor do evento.

Na página "Credenciais" do seu projeto, anote também os IDs do cliente que você usa para o Fazer login com o Google ou o Login do Google (legado). Normalmente, você tem um ID do cliente para cada plataforma compatível. Você vai precisar desses IDs do cliente para validar os tokens de evento de segurança, conforme descrito na próxima seção.

Para ativar a API RISC:

  1. Abra a página da API RISC no API Console. Verifique se o projeto usado para acessar os Serviços do Google ainda está selecionado.

  2. Leia os Termos do RISC e entenda os requisitos.

    Se você estiver ativando a API para um projeto de propriedade de uma organização, verifique se tem autorização para vincular sua organização aos Termos RISC.

  3. Clique em Ativar apenas se você concordar com os termos do RISC.

Criar um endpoint de receptor de eventos

Para receber notificações de ocorrências de segurança do Google, crie um endpoint HTTPS que processe solicitações HTTPS POST. Depois que você registrar esse endpoint (confira abaixo), o Google vai começar a postar no endpoint strings assinadas criptograficamente chamadas tokens de evento de segurança. Os tokens de evento de segurança são JWTs assinados que contêm informações sobre um único evento relacionado à segurança.

Para cada token de evento de segurança recebido no endpoint, primeiro valide e decodifique o token e, em seguida, processe o evento de segurança conforme apropriado para seu serviço. É essencial (link em inglês) validar o token de evento antes de decodificar para evitar ataques maliciosos de usuários de má-fé. As seções a seguir descrevem essas tarefas:

1. Decodificar e validar o token de evento de segurança

Como os tokens de evento de segurança são um tipo específico de JWT, é possível usar qualquer biblioteca JWT, como a listada em jwt.io, para decodificá-los e validá-los. Seja qual for a biblioteca usada, seu código de validação de token precisa fazer o seguinte:

  1. Consiga o identificador do emissor da Proteção entre contas (issuer) e o URI do certificado da chave de assinatura (jwks_uri) do documento de configuração RISC do Google, que pode ser encontrado em https://accounts.google.com/.well-known/risc-configuration.
  2. Usando a biblioteca JWT de sua escolha, veja o ID da chave de assinatura no cabeçalho do token de evento de segurança.
  3. No documento do certificado de chave de assinatura do Google, veja a chave pública com o ID da chave que você recebeu na etapa anterior. Se o documento não tiver uma chave com o ID que você está procurando, é provável que o token de evento de segurança seja inválido e o endpoint retorne o erro HTTP 400.
  4. Usando a biblioteca JWT de sua escolha, verifique o seguinte:
    • O token de evento de segurança é assinado usando a chave pública que você recebeu na etapa anterior.
    • A declaração aud do token é um dos IDs do cliente dos seus apps.
    • A declaração iss do token corresponde ao identificador do emissor recebido do documento de descoberta RISC. Não é necessário verificar a expiração do token (exp) porque os tokens de evento de segurança representam eventos históricos e, como tal, não expiram.

Exemplo:

Java

Como usar java-jwt e jwks-rsa-java:

public DecodedJWT validateSecurityEventToken(String token) {
    DecodedJWT jwt = null;
    try {
        // In a real implementation, get these values from
        // https://accounts.google.com/.well-known/risc-configuration
        String issuer = "accounts.google.com";
        String jwksUri = "https://www.googleapis.com/oauth2/v3/certs";

        // Get the ID of the key used to sign the token.
        DecodedJWT unverifiedJwt = JWT.decode(token);
        String keyId = unverifiedJwt.getKeyId();

        // Get the public key from Google.
        JwkProvider googleCerts = new UrlJwkProvider(new URL(jwksUri), null, null);
        PublicKey publicKey = googleCerts.get(keyId).getPublicKey();

        // Verify and decode the token.
        Algorithm rsa = Algorithm.RSA256((RSAPublicKey) publicKey, null);
        JWTVerifier verifier = JWT.require(rsa)
                .withIssuer(issuer)
                // Get your apps' client IDs from the API console:
                // https://console.developers.google.com/apis/credentials?project=_
                .withAudience("123456789-abcedfgh.apps.googleusercontent.com",
                              "123456789-ijklmnop.apps.googleusercontent.com",
                              "123456789-qrstuvwx.apps.googleusercontent.com")
                .acceptLeeway(Long.MAX_VALUE)  // Don't check for expiration.
                .build();
        jwt = verifier.verify(token);
    } catch (JwkException e) {
        // Key not found. Return HTTP 400.
    } catch (InvalidClaimException e) {

    } catch (JWTDecodeException exception) {
        // Malformed token. Return HTTP 400.
    } catch (MalformedURLException e) {
        // Invalid JWKS URI.
    }
    return jwt;
}

Python

import json
import jwt       # pip install pyjwt
import requests  # pip install requests

def validate_security_token(token, client_ids):
    # Get Google's RISC configuration.
    risc_config_uri = 'https://accounts.google.com/.well-known/risc-configuration'
    risc_config = requests.get(risc_config_uri).json()

    # Get the public key used to sign the token.
    google_certs = requests.get(risc_config['jwks_uri']).json()
    jwt_header = jwt.get_unverified_header(token)
    key_id = jwt_header['kid']
    public_key = None
    for key in google_certs['keys']:
        if key['kid'] == key_id:
            public_key = jwt.algorithms.RSAAlgorithm.from_jwk(json.dumps(key))
    if not public_key:
        raise Exception('Public key certificate not found.')
        # In this situation, return HTTP 400

    # Decode the token, validating its signature, audience, and issuer.
    try:
        token_data = jwt.decode(token, public_key, algorithms='RS256',
                                options={'verify_exp': False},
                                audience=client_ids, issuer=risc_config['issuer'])
    except:
        raise
        # Validation failed. Return HTTP 400.
    return token_data

# Get your apps' client IDs from the API console:
# https://console.developers.google.com/apis/credentials?project=_
client_ids = ['123456789-abcedfgh.apps.googleusercontent.com',
              '123456789-ijklmnop.apps.googleusercontent.com',
              '123456789-qrstuvwx.apps.googleusercontent.com']
token_data = validate_security_token(token, client_ids)

Se o token é válido e foi decodificado com sucesso, retorna o status HTTP 202. Em seguida, processe o evento de segurança indicado pelo token.

2. Gerenciar ocorrências de segurança

Quando decodificado, um token de evento de segurança é semelhante ao exemplo a seguir:

{
  "iss": "https://accounts.google.com/",
  "aud": "123456789-abcedfgh.apps.googleusercontent.com",
  "iat": 1508184845,
  "jti": "756E69717565206964656E746966696572",
  "events": {
    "https://schemas.openid.net/secevent/risc/event-type/account-disabled": {
      "subject": {
        "subject_type": "iss-sub",
        "iss": "https://accounts.google.com/",
        "sub": "7375626A656374"
      },
      "reason": "hijacking"
    }
  }
}

As declarações iss e aud indicam o emissor do token (Google) e o destinatário pretendido do token (seu serviço). Você verificou essas declarações na etapa anterior.

A declaração jti é uma string que identifica um único evento de segurança e é exclusiva para o stream. Use esse identificador para rastrear quais eventos de segurança você recebeu.

A declaração events contém informações sobre o evento de segurança que o token representa. Essa declaração é um mapeamento de um identificador de tipo de evento para uma declaração subject, que especifica o usuário a que esse evento se refere e outros detalhes sobre o evento que pode estar disponível.

A declaração subject identifica um usuário específico com o ID exclusivo da Conta do Google (sub). Esse ID é o mesmo identificador (sub) contido nos tokens de ID JWT emitidos pela biblioteca mais recente do recurso Fazer login com o Google (JavaScript, HTML), pela biblioteca legada do Login do Google ou pelo OpenID Connect. Quando o subject_type da declaração é id_token_claims, também pode incluir um campo email com o endereço de e-mail do usuário.

Use as informações na declaração events para tomar as medidas adequadas para o tipo de evento na conta do usuário especificado.

Identificadores de tokens OAuth

Para eventos OAuth sobre tokens individuais, o tipo de identificador do sujeito do token contém os seguintes campos:

  • token_type: somente refresh_token é compatível.

  • token_identifier_alg: consulte os possíveis valores na tabela abaixo.

  • token: consulte a tabela abaixo.

token_identifier_alg token
prefix Os primeiros 16 caracteres do token.
hash_base64_sha512_sha512 O hash duplo do token usando SHA-512.

Se você se integrar a esses eventos, sugerimos indexar os tokens com base nesses valores possíveis para garantir uma correspondência rápida quando o evento for recebido.

Tipos de evento compatíveis

A Proteção entre contas é compatível com os seguintes tipos de ocorrências de segurança:

Tipo de evento Attributes Como responder
https://schemas.openid.net/secevent/risc/event-type/sessions-revoked Obrigatório: proteja a conta do usuário encerrando as sessões abertas no momento.
https://schemas.openid.net/secevent/oauth/event-type/tokens-revoked

Obrigatório: se o token for para o Login do Google, encerre as sessões abertas no momento. Além disso, é possível sugerir ao usuário a configuração de um método de login alternativo.

Sugestão: se o token for destinado ao acesso a outras APIs do Google, exclua todos os tokens OAuth do usuário que você armazenou.

https://schemas.openid.net/secevent/oauth/event-type/token-revoked Consulte a seção Identificadores de token OAuth para mais informações sobre identificadores de token.

Obrigatório: se você armazenar o token de atualização correspondente, exclua-o e solicite um novo consentimento do usuário na próxima vez que um token de acesso for necessário.

https://schemas.openid.net/secevent/risc/event-type/account-disabled reason=hijacking,
reason=bulk-account

Obrigatório: se o motivo da desativação da conta era hijacking, proteja a conta do usuário encerrando as sessões abertas no momento.

Sugestão: se o motivo da desativação da conta era bulk-account, analise a atividade do usuário no seu serviço e determine as ações de acompanhamento apropriadas.

Sugestão: se nenhum motivo for informado, desative o Login do Google para o usuário e desative a recuperação de conta usando o endereço de e-mail associado à Conta do Google do usuário (geralmente, mas não necessariamente, uma conta do Gmail). Ofereça ao usuário um método de login alternativo.

https://schemas.openid.net/secevent/risc/event-type/account-enabled Sugestão: reative o Login do Google para o usuário e reative a recuperação com o endereço de e-mail da Conta do Google do usuário.
https://schemas.openid.net/secevent/risc/event-type/account-credential-change-required Sugestão: fique de olho em atividades suspeitas no seu serviço e tome as medidas apropriadas.
https://schemas.openid.net/secevent/risc/event-type/verification state=state Sugestão: registra o recebimento de um token de teste.

Eventos duplicados e perdidos

A Proteção entre contas tentará reenviar eventos que ela acredita não serem entregues. Portanto, você pode receber o mesmo evento várias vezes. Se isso puder causar ações repetidas que incomodem os usuários, use a declaração jti (que é um identificador exclusivo de um evento) para eliminar a duplicação dos eventos. Há ferramentas externas, como o Google Cloud Dataflow, que podem ajudar a executar o fluxo de dados de eliminação de duplicação.

Os eventos são entregues com novas tentativas limitadas. Portanto, se o receptor ficar inativo por um período prolongado, você poderá perder permanentemente alguns eventos.

Registrar o destinatário

Para começar a receber eventos de segurança, registre o endpoint receptor usando a API RISC. As chamadas para a API RISC precisam ser acompanhadas de um token de autorização.

Você receberá eventos de segurança apenas para os usuários do seu aplicativo. Portanto, configure uma tela de permissão OAuth no projeto do GCP como pré-requisito para as etapas descritas abaixo.

1. Gerar um token de autorização

Para gerar um token de autorização para a API RISC, crie um JWT com as seguintes declarações:

{
  "iss": SERVICE_ACCOUNT_EMAIL,
  "sub": SERVICE_ACCOUNT_EMAIL,
  "aud": "https://risc.googleapis.com/google.identity.risc.v1beta.RiscManagementService",
  "iat": CURRENT_TIME,
  "exp": CURRENT_TIME + 3600
}

Assine o JWT usando a chave privada da conta de serviço, que pode ser encontrada no arquivo JSON transferido por download ao criar a chave da conta de serviço.

Exemplo:

Java

Como usar java-jwt e a biblioteca de autenticação do Google:

public static String makeBearerToken() {
    String token = null;
    try {
        // Get signing key and client email address.
        FileInputStream is = new FileInputStream("your-service-account-credentials.json");
        ServiceAccountCredentials credentials =
               (ServiceAccountCredentials) GoogleCredentials.fromStream(is);
        PrivateKey privateKey = credentials.getPrivateKey();
        String keyId = credentials.getPrivateKeyId();
        String clientEmail = credentials.getClientEmail();

        // Token must expire in exactly one hour.
        Date issuedAt = new Date();
        Date expiresAt = new Date(issuedAt.getTime() + 3600000);

        // Create signed token.
        Algorithm rsaKey = Algorithm.RSA256(null, (RSAPrivateKey) privateKey);
        token = JWT.create()
                .withIssuer(clientEmail)
                .withSubject(clientEmail)
                .withAudience("https://risc.googleapis.com/google.identity.risc.v1beta.RiscManagementService")
                .withIssuedAt(issuedAt)
                .withExpiresAt(expiresAt)
                .withKeyId(keyId)
                .sign(rsaKey);
    } catch (ClassCastException e) {
        // Credentials file doesn't contain a service account key.
    } catch (IOException e) {
        // Credentials file couldn't be loaded.
    }
    return token;
}

Python

import json
import time

import jwt  # pip install pyjwt

def make_bearer_token(credentials_file):
    with open(credentials_file) as service_json:
        service_account = json.load(service_json)
        issuer = service_account['client_email']
        subject = service_account['client_email']
        private_key_id = service_account['private_key_id']
        private_key = service_account['private_key']
    issued_at = int(time.time())
    expires_at = issued_at + 3600
    payload = {'iss': issuer,
               'sub': subject,
               'aud': 'https://risc.googleapis.com/google.identity.risc.v1beta.RiscManagementService',
               'iat': issued_at,
               'exp': expires_at}
    encoded = jwt.encode(payload, private_key, algorithm='RS256',
                         headers={'kid': private_key_id})
    return encoded

auth_token = make_bearer_token('your-service-account-credentials.json')

Esse token de autorização pode ser usado para fazer chamadas de API RISC por uma hora. Quando o token expirar, gere um novo para continuar a fazer chamadas de API RISC.

2. Chamar a API de configuração de fluxo RISC

Agora que você tem um token de autorização, use a API RISC para configurar o fluxo de eventos de segurança do seu projeto, incluindo o registro do endpoint receptor.

Para isso, faça uma solicitação HTTPS POST para https://risc.googleapis.com/v1beta/stream:update, especificando o endpoint do receptor e os tipos de eventos de segurança do seu interesse:

POST /v1beta/stream:update HTTP/1.1
Host: risc.googleapis.com
Authorization: Bearer AUTH_TOKEN

{
  "delivery": {
    "delivery_method":
      "https://schemas.openid.net/secevent/risc/delivery-method/push",
    "url": RECEIVER_ENDPOINT
  },
  "events_requested": [
    SECURITY_EVENT_TYPES
  ]
}

Exemplo:

Java

public static void configureEventStream(final String receiverEndpoint,
                                        final List<String> eventsRequested,
                                        String authToken) throws IOException {
    ObjectMapper jsonMapper = new ObjectMapper();
    String streamConfig = jsonMapper.writeValueAsString(new Object() {
        public Object delivery = new Object() {
            public String delivery_method =
                    "https://schemas.openid.net/secevent/risc/delivery-method/push";
            public String url = receiverEndpoint;
        };
        public List<String> events_requested = eventsRequested;
    });

    HttpPost updateRequest = new HttpPost("https://risc.googleapis.com/v1beta/stream:update");
    updateRequest.addHeader("Content-Type", "application/json");
    updateRequest.addHeader("Authorization", "Bearer " + authToken);
    updateRequest.setEntity(new StringEntity(streamConfig));

    HttpResponse updateResponse = new DefaultHttpClient().execute(updateRequest);
    Header[] responseContentTypeHeaders = updateResponse.getHeaders("Content-Type");
    StatusLine responseStatus = updateResponse.getStatusLine();
    int statusCode = responseStatus.getStatusCode();
    HttpEntity entity = updateResponse.getEntity();
    // Now handle response
}

// ...

configureEventStream(
        "https://your-service.example.com/security-event-receiver",
        Arrays.asList(
                "https://schemas.openid.net/secevent/risc/event-type/account-credential-change-required",
                "https://schemas.openid.net/secevent/risc/event-type/account-disabled"),
        authToken);

Python

import requests

def configure_event_stream(auth_token, receiver_endpoint, events_requested):
    stream_update_endpoint = 'https://risc.googleapis.com/v1beta/stream:update'
    headers = {'Authorization': 'Bearer {}'.format(auth_token)}
    stream_cfg = {'delivery': {'delivery_method': 'https://schemas.openid.net/secevent/risc/delivery-method/push',
                               'url': receiver_endpoint},
                  'events_requested': events_requested}
    response = requests.post(stream_update_endpoint, json=stream_cfg, headers=headers)
    response.raise_for_status()  # Raise exception for unsuccessful requests

configure_event_stream(auth_token, 'https://your-service.example.com/security-event-receiver',
                       ['https://schemas.openid.net/secevent/risc/event-type/account-credential-change-required',
                        'https://schemas.openid.net/secevent/risc/event-type/account-disabled'])

Se a solicitação retornar HTTP 200, o fluxo de eventos foi configurado com sucesso e o endpoint do receptor começará a receber tokens de eventos de segurança. A próxima seção descreve como testar a configuração e o endpoint do stream para verificar se tudo está funcionando corretamente juntos.

Receber e atualizar sua configuração de stream atual

Se, no futuro, você quiser modificar a configuração do stream, faça uma solicitação GET autorizada a https://risc.googleapis.com/v1beta/stream para receber a configuração de stream atual, modifique o corpo da resposta e, em seguida, execute o POST da configuração modificada de volta para https://risc.googleapis.com/v1beta/stream:update, conforme descrito acima.

Parar e retomar o fluxo de eventos

Se você precisar interromper o fluxo de eventos do Google, faça uma solicitação POST autorizada para https://risc.googleapis.com/v1beta/stream/status:update com { "status": "disabled" } no corpo da solicitação. Enquanto o stream estiver desativado, o Google não enviará eventos ao seu endpoint e não vai armazenar em buffer os eventos de segurança quando eles ocorrem. Para reativar o fluxo de eventos, use POST { "status": "enabled" } no mesmo endpoint.

3. Opcional: testar a configuração do stream

É possível verificar se a configuração do stream e o endpoint do receptor estão funcionando corretamente enviando um token de verificação pelo stream de eventos. Esse token pode conter uma string exclusiva que pode ser usada para verificar se o token foi recebido no endpoint. Para usar esse fluxo, inscreva-se no tipo de evento https://schemas.openid.net/secevent/risc/event-type/verification ao registrar seu receptor.

Para solicitar um token de verificação, faça uma solicitação HTTPS POST autorizada para https://risc.googleapis.com/v1beta/stream:verify. No corpo da solicitação, especifique uma string de identificação:

{
  "state": "ANYTHING"
}

Exemplo:

Java

public static void testEventStream(final String stateString,
                                   String authToken) throws IOException {
    ObjectMapper jsonMapper = new ObjectMapper();
    String json = jsonMapper.writeValueAsString(new Object() {
        public String state = stateString;
    });

    HttpPost updateRequest = new HttpPost("https://risc.googleapis.com/v1beta/stream:verify");
    updateRequest.addHeader("Content-Type", "application/json");
    updateRequest.addHeader("Authorization", "Bearer " + authToken);
    updateRequest.setEntity(new StringEntity(json));

    HttpResponse updateResponse = new DefaultHttpClient().execute(updateRequest);
    Header[] responseContentTypeHeaders = updateResponse.getHeaders("Content-Type");
    StatusLine responseStatus = updateResponse.getStatusLine();
    int statusCode = responseStatus.getStatusCode();
    HttpEntity entity = updateResponse.getEntity();
    // Now handle response
}

// ...

testEventStream("Test token requested at " + new Date().toString(), authToken);

Python

import requests
import time

def test_event_stream(auth_token, nonce):
    stream_verify_endpoint = 'https://risc.googleapis.com/v1beta/stream:verify'
    headers = {'Authorization': 'Bearer {}'.format(auth_token)}
    state = {'state': nonce}
    response = requests.post(stream_verify_endpoint, json=state, headers=headers)
    response.raise_for_status()  # Raise exception for unsuccessful requests

test_event_stream(auth_token, 'Test token requested at {}'.format(time.ctime()))

Se a solicitação for bem-sucedida, o token de verificação será enviado para o endpoint que você registrou. Em seguida, por exemplo, se o endpoint processar tokens de verificação simplesmente registrando-os, você poderá examinar os registros para confirmar se o token foi recebido.

Referência do código de erro

Os erros a seguir podem ser retornados pela API RISC:

Código do erro Mensagem de erro Ações sugeridas
400 A configuração de stream precisa conter o campo $fieldname. Sua solicitação para o endpoint https://risc.googleapis.com/v1beta/stream:update é inválida ou não pode ser analisada. Inclua $fieldname em sua solicitação.
401 (link em inglês) Não autorizado. Falha na autorização. Verifique se você anexou um token de autorização à solicitação e se o token é válido e não expirou.
403 (link em inglês) O endpoint de entrega precisa ser um URL HTTPS. O endpoint de entrega (ou seja, o endpoint em que você espera que os eventos RISC sejam entregues) precisa ser HTTPS. Não enviamos eventos RISC para URLs HTTP.
403 (link em inglês) A configuração de stream não tem um método de entrega em conformidade com as especificações para RISC. Seu projeto do Google Cloud já precisa ter uma configuração RISC. Se você estiver usando o Firebase e tiver o Login do Google ativado, o Firebase gerenciará o RISC para seu projeto. Não será possível criar uma configuração personalizada. Se você não estiver usando o Login do Google no seu projeto do Firebase, desative-o e tente atualizar novamente após uma hora.
403 (link em inglês) Não foi possível encontrar o projeto. Verifique se você está usando a conta de serviço correta para o projeto certo. Talvez você esteja usando uma conta de serviço associada a um projeto excluído. Saiba como ver todas as contas de serviço associadas a um projeto.
403 (link em inglês) A conta de serviço precisa de permissão para acessar sua configuração RISC Acesse o API Console do projeto e atribua o papel "Administrador de configuração RISC" (roles/riscconfigs.admin) à conta de serviço que está fazendo as chamadas para seu projeto, seguindo estas instruções.
403 (link em inglês) As APIs de gerenciamento de stream só podem ser chamadas por uma conta de serviço. Veja mais informações sobre como chamar APIs do Google com uma conta de serviço.
403 (link em inglês) O endpoint de entrega não pertence a nenhum dos domínios do seu projeto. Todo projeto tem um conjunto de domínios autorizados. Se o endpoint de entrega (ou seja, o endpoint em que você espera que os eventos RISC sejam entregues) não estiver hospedado em um deles, será necessário adicionar o domínio do endpoint a esse conjunto.
403 (link em inglês) Para usar essa API, seu projeto precisa ter pelo menos um cliente OAuth configurado. O RISC só funciona se você criar um app compatível com o Login do Google. Esta conexão requer um cliente OAuth. Se seu projeto não tiver clientes OAuth, é provável que o RISC não seja útil para você. Saiba mais sobre como o Google usa o OAuth para nossas APIs.
403 (link em inglês)

Status incompatível.

Status de inválido(a).

No momento, só aceitamos os status de transmissão "enabled" e "disabled".
404 (link em inglês)

O projeto não tem configuração RISC.

O projeto não tem configuração RISC atual e não é possível atualizar o status.

Chame o endpoint https://risc.googleapis.com/v1beta/stream:update para criar uma nova configuração de stream.
4XX/5XX Não foi possível atualizar o status. Consulte a mensagem de erro detalhada para mais informações.

Escopos do token de acesso

Se você decidir usar tokens de acesso para se autenticar na API RISC, estes são os escopos que seu aplicativo precisa solicitar:

Endpoint Escopo
https://risc.googleapis.com/v1beta/stream/status https://www.googleapis.com/auth/risc.status.readonly OU https://www.googleapis.com/auth/risc.status.readwrite
https://risc.googleapis.com/v1beta/stream/status:update https://www.googleapis.com/auth/risc.status.readwrite
https://risc.googleapis.com/v1beta/stream https://www.googleapis.com/auth/risc.configuration.readonly OU https://www.googleapis.com/auth/risc.configuration.readwrite
https://risc.googleapis.com/v1beta/stream:update https://www.googleapis.com/auth/risc.configuration.readwrite
https://risc.googleapis.com/v1beta/stream:verify https://www.googleapis.com/auth/risc.verify

Precisa de ajuda?

Primeiro, confira nossa seção de referência do código de erro. Se você ainda tiver dúvidas, poste-as no Stack Overflow com a tag #SecEvents.