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 por meio do Console do Google Cloud. Essas APIs e SDKs exigem o uso de JSON Web Tokens (JWTs) assinados com contas de serviço criadas no Console do Cloud.

Informações gerais

Como parte do mecanismo de autorização, o Fleet Engine fornece segurança extra de chamadas originadas de ambientes de baixa confiança. Os ambientes de baixa confiança incluem smartphones e navegadores. Além disso, o Fleet Engine emprega o princípio de privilégio mínimo, 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 da segurança, que é criptografada em um JWT que você transmite 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, o papel SuperUser tem permissão para fazer tudo, enquanto a função Driver não confiável só pode executar atualizações mínimas de local.

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

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

  • 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 apropriado que você pode transmitir para o Fleet Engine, seu 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 o autor da chamada emitir a chamada de API.

    2. As declarações do JWT transmitidas na solicitação fornecem a autorização correta para o autor da chamada operar 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 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. No painel de APIs e serviços, ative a API Local Rides e Deliveries.

Contas de serviço e papéis do IAM

A conta de serviço é um tipo especial de conta usada por um aplicativo, em vez de 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 solução Last Mile Fleet 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 criados por uma conta de serviço com esse papel normalmente são usados nos dispositivos móveis do motorista de entrega ou nos servidores de back-end.
Usuário de driver 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 criados por uma conta de serviço com esse papel geralmente são usados nos dispositivos móveis dos motoristas 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, informações da tarefa. Os tokens criados 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 da frota de entrega do Fleet Engine

roles/fleetengine.deliveryFleetReader
Concede permissão para ler veículos de entrega e tarefas, além de pesquisar tarefas usando um ID de rastreamento. Os tokens criados por uma conta de serviço com esse papel geralmente são usados a partir do 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 do 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 que oferecem suporte às políticas "traga seu próprio dispositivo" precisam optar pela segurança do papel de usuário não confiável do Fleet Engine e confiar apenas no 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 que um conjunto arbitrário de permissões seja agrupado. Os SDKs de driver e 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 dos 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 da conta de serviço permitirá que eles criem tokens com as 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 a 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.
  • Fornecer mecanismos de assinatura de token que não sejam arquivos de credenciais (como a representação de uma conta de serviço).
  • Anexa tokens assinados a solicitações de saída feitas de um stub gRPC ou de um cliente GAPIC.

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 é altamente recomendável 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 do 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 do token, os serviços a que o token está reivindicando acesso e outras informações de autorização para reduzir o escopo do acesso, por exemplo, o ID do veículo de entrega.

Uma 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 conta de serviço. Encontre esse valor no campo "private_key_id" do arquivo JSON da sua conta de serviço. Use uma chave de uma conta de serviço com o nível de permissões correto.

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

CampoDescrição
iss Endereço de e-mail da sua conta de serviço.
sub 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 Carimbo de data/hora em que o token foi criado, especificado em segundos decorridos desde 00:00:00 UTC, 1o de janeiro de 1970. 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 Carimbo de data/hora da expiração do token, especificado em segundos decorridos desde 00:00:00 UTC, 1o de janeiro de 1970. 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 criaçã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 declarações particulares. 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 JSON Web Token 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. Dependendo da função do motorista, os tokens permitem o acesso apenas para o ID do veículo de entrega específico, e não para outros IDs arbitrários.

A Last Mile Fleet Solution usa as seguintes declaraçõ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 e 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 o 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 apropriada quando você estiver 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 desenvolvedor de identidade.

O mecanismo para anexar o token a uma chamada gRPC depende da linguagem e do framework usados 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 a partir 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": ["*"]
       }
    }

O exemplo a seguir mostra um token para uma operação por veículo de entrega a partir 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 motorista:

    {
      "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 conta de serviço. Esse valor pode ser encontrado no campo private_key_id do arquivo JSON da sua conta de serviço.
  • Nos campos iss e sub, especifique o endereço de e-mail da conta de serviço. Esse valor pode ser encontrado 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 em que 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 da expiração do token em segundos desde 1o de janeiro de 1970, às 00:00:00 UTC. O valor recomendado é iat + 3.600.

Ao assinar o token que 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 deveria ter acesso.