Autenticação e autorização

Nesta seção, explicamos os conceitos de autenticação e autorização em relação à implementação do Fleet Engine. Ele detalha os procedimentos que você precisa realizar para proteger as chamadas de função do Fleet Engine.

É possível configurar os recursos fornecidos pela solução Last Mile Fleet pelo Console do Google Cloud. Essas APIs e SDKs exigem o uso de JSON Web Tokens (JWTs) que foi assinado usando contas de serviço criadas no Console do Cloud.

Visão geral

Como parte do mecanismo de autorização, o Fleet Engine oferece segurança extra em relação a chamadas originadas de ambientes de baixa confiança. Ambientes de baixa confiança incluem smartphones e navegadores. Além disso, o Fleet Engine usa o princípio de privilégio mínimo (em inglês), em que uma chamada precisa receber apenas os privilégios necessários para concluir a tarefa.

Para proteger chamadas de função originadas de ambientes de baixa confiança, o Google projetou um mecanismo em que seu código cria um token no servidor de back-end, que é um ambiente totalmente confiável. Cada chamada tem uma descrição completa de segurança, que é criptografada em um JWT transmitido com a chamada de qualquer ambiente.

Princípios de design de autenticação

O fluxo de autenticação do Fleet Engine incorpora os princípios de design a seguir.

  • Os papéis do IAM definem o escopo da atividade permitida para o autor da chamada. Por exemplo, a função SuperUser tem permissão para fazer tudo, enquanto a função SuperUser só pode realizar atualizações mínimas de local.

  • Os papéis do IAM estão associados às contas de serviço.

  • As declarações JWT restringem ainda mais as entidades em que o autor da chamada pode operar. Podem ser tarefas específicas ou veículos de entrega.

  • As solicitações enviadas ao Fleet Engine sempre contêm um JWT.

    • Como os JWTs estão associados a contas de serviço, as solicitações enviadas ao Fleet Engine são implicitamente associadas à conta de serviço associada ao JWT.
  • Para solicitar o JWT adequado que pode ser transmitido para o Fleet Engine, o código em execução em um ambiente de baixa confiança precisa primeiro chamar o código em execução em um ambiente totalmente confiável.

  • O Fleet Engine executa as seguintes verificações de segurança:

    1. Os papéis do IAM associados à conta de serviço fornecem a autorização correta para que o autor da chamada emita a chamada de API.

    2. As declarações de JWT transmitidas na solicitação fornecem a autorização correta para que o autor da chamada opere na entidade.

Fluxo de autenticação

O diagrama de sequência a seguir demonstra esses detalhes do fluxo de autenticação.

  1. O administrador da frota cria contas de serviço.

  2. O administrador da frota atribui papéis específicos do IAM às contas de serviço.

  3. O administrador da frota configura o back-end com as contas de serviço.

  4. O app cliente solicita um JWT do back-end do parceiro. O solicitante pode ser o app do motorista, do consumidor ou de monitoramento.

  5. O Fleet Engine emite um JWT para a respectiva conta de serviço. O app cliente recebe o JWT.

  6. O app cliente usa o JWT para se conectar ao Fleet Engine e ler ou modificar dados, dependendo dos papéis do IAM atribuídos a ele durante a fase de configuração.

Diagrama de sequência de autenticação

Configuração do projeto do Google Cloud

Para configurar o projeto na nuvem, primeiro crie o projeto e, em seguida, crie contas de serviço.

Para criar seu projeto do Google Cloud:

  1. Crie um projeto do Google Cloud usando o console do Google Cloud.
  2. Usando o painel de APIs e serviços, ative a API Local Rides and Deliveries.

Contas de serviço e papéis do IAM

A conta de serviço é um tipo especial de conta usada por um aplicativo, e não por uma pessoa. Normalmente, uma conta de serviço é usada para criar JWTs que concedem diferentes conjuntos de permissões, dependendo do papel. Para reduzir a possibilidade de abuso, crie várias contas de serviço, cada uma com o conjunto mínimo de papéis necessários.

A Last Mile Fleet Solution usa os seguintes papéis:

PapelDescrição
Usuário de motorista confiável de entrega do Fleet Engine

roles/fleetengine.deliveryTrustedDriver
Concede permissão para criar e atualizar tarefas e veículos de entrega, incluindo a atualização do local do veículo de entrega e do status ou resultado da tarefa. Os tokens gerados por uma conta de serviço com esse papel costumam ser usados nos dispositivos móveis do motorista de entrega ou nos servidores de back-end.
Usuário de motorista não confiável de entrega do Fleet Engine

roles/fleetengine.deliveryUntrustedDriver
Concede permissão para atualizar a localização do veículo de entrega. Os tokens gerados por uma conta de serviço com esse papel geralmente são usados nos dispositivos móveis do motorista de entrega.
Usuário consumidor de entrega do Fleet Engine

roles/fleetengine.deliveryConsumer
Concede permissão para pesquisar tarefas usando um ID de acompanhamento e ler, mas não atualizar, as informações da tarefa. Os tokens gerados por uma conta de serviço com esse papel geralmente são usados a partir do navegador da Web de um consumidor de entrega.
Superusuário de entrega do Fleet Engine

roles/fleetengine.deliverySuperUser
Concede permissão a todos os veículos de entrega e APIs de tarefas. Os tokens criados por uma conta de serviço com esse papel geralmente são usados nos servidores de back-end.
Leitor de frota de entrega do Fleet Engine

roles/fleetengine.deliveryFleetReader
Concede permissão para ler tarefas e veículos de entrega e pesquisar tarefas usando um ID de rastreamento. Os tokens gerados por uma conta de serviço com esse papel geralmente são usados no navegador da Web de um operador da frota de entrega.

As organizações que fornecem aos motoristas dispositivos gerenciados por TI corporativa podem aproveitar a flexibilidade oferecida pelo papel de usuário Motorista confiável do Fleet Engine e optar por integrar algumas ou todas as interações do Fleet Engine ao app para dispositivos móveis.

As organizações com suporte a políticas "traga seu próprio dispositivo" precisam optar pela segurança do papel de usuário de motorista não confiável do Fleet Engine e depender apenas do app para dispositivos móveis para enviar atualizações de localização do veículo ao Fleet Engine. Todas as outras interações precisam ser originadas dos servidores de back-end do cliente.

Os SDKs do driver e do consumidor são criados com base nesses papéis padrão. No entanto, é possível criar papéis personalizados que permitem o agrupamento de um conjunto arbitrário de permissões. Os SDKs do driver e do consumidor vão mostrar mensagens de erro quando uma permissão necessária estiver ausente. Por isso, é altamente recomendável usar o conjunto padrão de papéis apresentado acima, em vez de papéis personalizados.

Como criar uma conta de serviço

É possível criar uma conta de serviço usando a guia IAM & Admin > Service Accounts no Console do Google Cloud. Na lista suspensa "Papel", selecione Fleet Engine e atribua um dos papéis à conta de serviço. É uma prática recomendada indicar a conta associada a cada papel. Por exemplo, dê um nome significativo à conta de serviço.

Por conveniência, se você precisar criar JWTs para clientes não confiáveis, adicionar usuários ao papel de Criador de token de conta de serviço permite que eles criem tokens com ferramentas de linha de comando gcloud.

gcloud projects add-iam-policy-binding project-id \
       --member=user:my-user@example.com \
       --role=roles/iam.serviceAccountTokenCreator

Em que my-user@example.com é o e-mail usado para autenticação com gcloud (gcloud auth list --format='value(account)').

Biblioteca de autenticação do Fleet Engine

O Fleet Engine usa JWTs para restringir o acesso às APIs do Fleet Engine. A nova biblioteca de autenticação do Fleet Engine, disponível no GitHub, simplifica a criação de JWTs do Fleet Engine e os assina com segurança.

A biblioteca oferece os seguintes benefícios:

  • Simplifica o processo de criação de tokens do Fleet Engine.
  • Oferece mecanismos de assinatura de token além do uso de arquivos de credenciais (como a representação de uma conta de serviço).
  • Anexa tokens assinados às solicitações de saída feitas de um stub gRPC ou de um cliente GAPIC.

Como criar um JSON Web Token (JWT) para autorização

Quando você não usa a biblioteca de autenticação do Fleet Engine, os JWTs precisam ser criados diretamente na base de código. Isso exige um entendimento profundo sobre os JWTs e a relação deles com o Fleet Engine. É por isso que recomendamos que você use a biblioteca de autenticação do Fleet Engine.

No Fleet Engine, os JWTs fornecem autenticação de curta duração e garantem que os dispositivos só possam modificar veículos ou tarefas para os quais estão autorizados. Os JWTs contêm um cabeçalho e uma seção de declaração. A seção de cabeçalho contém informações como a chave privada a ser usada (recebida das contas de serviço) e o algoritmo de criptografia. A seção de declaração contém informações como o horário de criação do token, a vida útil dele, os serviços a que o token está reivindicando acesso e outras informações de autorização para restringir o escopo de acesso. Por exemplo, o ID do veículo de entrega.

A seção de cabeçalho JWT contém os seguintes campos:

CampoDescrição
alg O algoritmo a ser usado. "RS256".
typ O tipo de token. "JWT".
criança O ID da chave privada da sua conta de serviço. Esse valor está no campo "private_key_id" do arquivo JSON da conta de serviço. Use uma chave de uma conta de serviço com o nível de permissões correto.

A seção de declarações do JWT contém os seguintes campos:

CampoDescrição
iss O endereço de e-mail da sua conta de serviço.
sub O endereço de e-mail da sua conta de serviço.
aud O SERVICE_NAME da sua conta de serviço, neste caso https://fleetengine.googleapis.com/
iat O carimbo de data/hora em que o token foi criado, especificado em segundos desde 1o de janeiro de 1970, às 00:00:00 UTC. Aguarde 10 minutos para o desvio. Se o carimbo de data/hora estiver muito distante no passado ou no futuro, o servidor pode relatar um erro.
exp O carimbo de data/hora da expiração do token, especificado em segundos desde 1o de janeiro de 1970, às 00:00:00 UTC. A solicitação falhará se o carimbo de data/hora for mais de uma hora no futuro.
autorização Dependendo do caso de uso, pode conter "deliveryvehicleid", "trackingid", "taskid" ou "taskids".

A geração de um token JWT refere-se a assiná-lo. Para instruções e exemplos de código para criar e assinar o JWT, consulte Autorização da conta de serviço sem OAuth. Em seguida, é possível anexar um token criado a chamadas gRPC ou outros métodos usados para acessar o Fleet Engine.

Declarações JWT

A Last Mile Fleet Solution usa reivindicações privadas. O uso de declarações particulares garante que apenas clientes autorizados possam acessar os próprios dados. Por exemplo, quando o back-end emite um token da Web JSON para o dispositivo móvel de um motorista de entrega, esse token precisa conter a declaração deliveryvehicleid com o valor do ID do veículo de entrega do motorista. Em seguida, dependendo da função do motorista, os tokens permitem o acesso apenas para o ID do veículo de envio específico, e não qualquer outro ID arbitrário do veículo.

A Last Mile Fleet Solution usa as seguintes reivindicações particulares:

  • deliveryvehicleid: use ao chamar APIs por veículo de entrega.
  • taskid: use ao chamar APIs por tarefa.
  • taskids: use ao chamar BatchCreateTasksAPI. Essa declaração precisa estar em formato de matriz, que deve conter todos os IDs de tarefas necessários para concluir a solicitação. Não inclua declarações delivervehicleid, trackingid ou taskid.
  • trackingid: use ao chamar SearchTasksAPI. A declaração precisa corresponder ao ID de acompanhamento na solicitação. Não inclua declarações delivervehicleid, taskid ou taskids.

O token também precisa conter a declaração adequada quando você está chamando APIs pelo servidor de back-end, mas é possível usar o valor especial de um asterisco ("*") para declarações deliveryvehicleid, taskid e trackingid. O asterisco ("*") também pode ser usado na declaração taskids, mas precisa ser o único elemento na matriz.

Se você quiser criar e assinar um JSON diretamente como portador de token, em vez de usar tokens de acesso do OAuth 2.0, leia as instruções para Autorização da conta de serviço sem OAuth na documentação do Identity Developer.

O mecanismo para anexar o token a uma chamada gRPC depende da linguagem e do framework usado para fazer a chamada. O mecanismo para especificar um token para uma chamada HTTP é incluir um cabeçalho de autorização com um token do portador cujo valor é o token, conforme indicado nas notas de autorização para casos de uso de rastreamento de envio individual ou desempenho da frota.

O exemplo a seguir mostra um token para uma operação por tarefa do servidor de back-end:

    {
      "alg": "RS256",
      "typ": "JWT",
      "kid": "private_key_id_of_provider_service_account"
    }
    .
    {
      "iss": "provider@yourgcpproject.iam.gserviceaccount.com",
      "sub": "provider@yourgcpproject.iam.gserviceaccount.com",
      "aud": "https://fleetengine.googleapis.com/",
      "iat": 1511900000,
      "exp": 1511903600,
      "authorization": {
         "taskid": "*"
       }
    }

O exemplo a seguir mostra um token para uma operação de criação de tarefas em lote do servidor de back-end:

    {
      "alg": "RS256",
      "typ": "JWT",
      "kid": "private_key_id_of_provider_service_account"
    }
    .
    {
      "iss": "provider@yourgcpproject.iam.gserviceaccount.com",
      "sub": "provider@yourgcpproject.iam.gserviceaccount.com",
      "aud": "https://fleetengine.googleapis.com/",
      "iat": 1511900000,
      "exp": 1511903600,
      "authorization": {
         "taskids": ["*"]
       }
    }

No exemplo a seguir, mostramos um token para uma operação por veículo de entrega do servidor de back-end:

    {
      "alg": "RS256",
      "typ": "JWT",
      "kid": "private_key_id_of_provider_service_account"
    }
    .
    {
      "iss": "provider@yourgcpproject.iam.gserviceaccount.com",
      "sub": "provider@yourgcpproject.iam.gserviceaccount.com",
      "aud": "https://fleetengine.googleapis.com/",
      "iat": 1511900000,
      "exp": 1511903600,
      "authorization": {
         "deliveryvehicleid": "*"
       }
    }

O exemplo a seguir mostra um token para clientes usuários finais:

    {
      "alg": "RS256",
      "typ": "JWT",
      "kid": "private_key_id_of_delivery_consumer_service_account"
    }
    .
    {
      "iss": "consumer@yourgcpproject.iam.gserviceaccount.com",
      "sub": "consumer@yourgcpproject.iam.gserviceaccount.com",
      "aud": "https://fleetengine.googleapis.com/",
      "iat": 1511900000,
      "exp": 1511903600,
      "authorization": {
         "trackingid": "shipment_12345"
       }
    }

O exemplo a seguir mostra um token para seu app de driver:

    {
      "alg": "RS256",
      "typ": "JWT",
      "kid": "private_key_id_of_delivery_driver_service_account"
    }
    .
    {
      "iss": "driver@yourgcpproject.iam.gserviceaccount.com",
      "sub": "driver@yourgcpproject.iam.gserviceaccount.com",
      "aud": "https://fleetengine.googleapis.com/",
      "iat": 1511900000,
      "exp": 1511903600,
      "authorization": {
         "deliveryvehicleid": "driver_12345"
       }
    }
  • Para o campo kid no cabeçalho, especifique o ID da chave privada da sua conta de serviço. Esse valor está no campo private_key_id do arquivo JSON da conta de serviço.
  • Nos campos iss e sub, especifique o endereço de e-mail da conta de serviço. Esse valor está no campo client_email do arquivo JSON da conta de serviço.
  • No campo aud, especifique https://SERVICE_NAME/.
  • No campo iat, especifique o carimbo de data/hora de quando o token foi criado, em segundos decorridos desde 1o de janeiro de 1970, às 00:00:00 UTC. Aguarde 10 minutos para o desvio. Se o carimbo de data/hora estiver muito distante no passado ou no futuro, o servidor pode relatar um erro.
  • No campo exp, especifique o carimbo de data/hora de quando o token expira, em segundos, a partir de 1o de janeiro de 1970, às 00:00:00 UTC. O valor recomendado é iat + 3.600.

Ao assinar o token a ser transmitido para um dispositivo móvel ou usuário final, use o arquivo de credenciais para o papel de Motorista de entrega ou Consumidor. Caso contrário, o dispositivo móvel ou o usuário final poderá alterar ou visualizar informações a que não deveriam ter acesso.