Observação:

Usar o OCI Functions e o OCI Queue para Autorizar Recursos do Usuário sem Expor o Privilégio de Administrador a Aprovadores

Introdução

A atualização dos recursos do usuário é uma necessidade importante para muitas empresas, especialmente quando a permissão autorizada aos usuários é sensível, como o recurso da console ou a chave de API. No entanto, na medida em que encontramos na documentação do OCI (Oracle Cloud Infrastructure), somente usuários do grupo de administradores podem autorizar a capacidade do usuário mesmo quando há políticas do OCI IAM (Oracle Cloud Infrastructure Identity and Access Management) que a permitem explicitamente. Para obter mais informações, consulte Gerenciando Usuários.

Este tutorial é para demonstrar uma solução para o cenário em que os usuários não estão no grupo de administradores de um domínio do OCI IAM, mas ainda precisam ter a capacidade de autorizar os recursos do usuário utilizando o recurso recém-lançado do OCI Connector Hub para integrar o OCI Queue e o OCI Functions.

Arquitetura de Solução

Descrição da ilustração SolutionArchitecture.png

Objetivos

Tarefa 1: Criar o Canal de Mensagens do OCI Queue para o OCI Functions

A parte essencial da solução é separar a permissão necessária alterando os recursos do usuário da permissão de que o aprovador precisa para aprovar uma solicitação.

  1. Crie o OCI Queue para solicitações de entrada. Para obter mais informações, consulte Criando uma Fila.

  2. Crie a Função do OCI usada para autorizar usuários. Para obter mais informações, consulte Criando Funções.

  3. Configure a integração do OCI Queue e do OCI Functions por meio do OCI Connector Hub. Certifique-se de que a origem esteja especificada com o OCI Queue criado e de que o destino seja o OCI Functions. Vamos deixar a tarefa opcional vazia neste tutorial. Para obter mais informações, consulte Anunciando a disponibilidade do OCI Queue como origem no OCI Connector Hub.

Tarefa 2: Configurar Políticas do OCI IAM e Grupo Dinâmico

Depois de dividir as atribuições do aprovador no OCI Queue para aceitar as solicitações e o OCI Functions para executar a solicitação, precisamos configurar políticas rigorosas do OCI IAM para garantir que a permissão não seja abusada. Como criamos essa solução para oferecer suporte a um cliente que insiste em usar o compartimento raiz para a implementação, demonstraremos todas as configurações do compartimento raiz para a parte do OCI IAM.

  1. Permitir que apenas o aprovador envie mensagens de fila para o OCI Queue de destino.

    Allow group 'testApprover' to use queues in tenancy
    

    Adicionando essa política, permitimos que os usuários do grupo testApprover usem a fila para receber as solicitações de acesso da console. Podemos colocar mais limitações no grupo especificando apenas a permissão no tipo de recurso queue-push, conforme mostrado no exemplo abaixo.

    use queue-push in compartment <compartment> where target.queue.id = '<queue_ocid>'
    
  2. Configure o grupo dinâmico para incluir o OCI Functions especificando a regra de correspondência a seguir.

    ALL{resource.type='fnfunc',resource.id='ocid.fnfunc.oc1.....'}
    

    Em seguida, esse grupo dinâmico será autorizado com uma atribuição do Oracle Identity Cloud Service para gerenciar os usuários no domínio.

  3. Configure a atribuição do grupo dinâmico do Oracle Identity Cloud Service.

    Função de Domínio do IDCS

    Descrição da ilustração DomainRole.png

  4. Configure as Funções do OCI para que só possam ser chamadas pelo OCI Queue. O exemplo a seguir limita apenas a origem da chamada às filas. Na verdade, podemos torná-la mais rigorosa usando tags nos recursos. Para obter mais informações, consulte Usando Tags para Gerenciar o Acesso

    Allow service faas to use functions-family in tenancy where request.principal.type='queues'
    

Tarefa 3: Criar o Código de Funções do OCI

Precisamos compor um trecho de código Python para que o OCI Functions execute realmente a solicitação obtida do OCI Queue.

  1. A mensagem do OCI Queue será passada para a função no objeto data.

    def handler(ctx, data: bytes = None) -> response.Response:
        try:
        # Parse the message from the OCI Queue
            if data:
            message = json.loads(data.getvalue().decode('utf-8'))
            else:
            message = "no useremail received"
    
  2. Faça a autenticação usando o controlador de recursos.

    Observação: A linha de código a seguir pode não estar funcionando em um IDE.

    identity = IdentityClient({}, signer=oci.auth.signers.get_resource_principals_signer(), region=region)
    
  3. Converta o e-mail do usuário passado para o OCID (Oracle Cloud Identifier) do usuário.

    def get_user_ocid_by_email(identity_client,email,tenancy_id):
        # List all users in the tenancy
        users = oci.pagination.list_call_get_all_results(identity_client.list_users,tenancy_id).data
    
        # Find the user with the matching email address
        for user in users:
            if user.email.lower() == email.lower():
                return user.id
    
        return None
    
  4. Atualize o recurso do usuário com o controlador de recursos usando a função IdentityClient.

    # Get the user by email address
    user_ocid = get_user_ocid_by_email(identity,user_email,tenancy)
    
    # Update user capabilities (example: enable API keys)
    update_details = oci.identity.models.UpdateUserCapabilitiesDetails(
        can_use_api_keys=True,
        can_use_auth_tokens=True,
        can_use_console_password=True,
        can_use_customer_secret_keys=True,
        can_use_db_credentials=True,
        can_use_o_auth2_client_credentials=True,
        can_use_smtp_credentials=True
    )
    
    # Update the user
    identity.update_user_capabilities(user_ocid, update_details)
    
  5. Implante o código da função na função OCI que acabamos de criar. Para obter etapas detalhadas de implantação de uma função do OCI, consulte Notas de Configuração para Funções do OCI

Tarefa 4: Testar as Alterações

Teste as alterações enviando uma mensagem para a fila de destino. Podemos usar a Console do OCI ou qualquer SDK, incluindo o OCI Cloud Shell.

Enviar mensagem

Descrição da ilustração send-message.png

Examinar

Descrição da ilustração examine.png

Diagnosticando e Solucionando Problemas

Configurando a Função do OCI para usar o OCIR

Se você estiver usando o OCIR como repositório da função do OCI, alguns problemas podem estar bloqueando você e não é tão fácil encontrar uma resolução quanto, por enquanto, nenhum guia claro é comprovado especificamente para evitar esses problemas.

  1. A configuração de um compartimento específico para o repositório do OCIR e para a função do OCI como o contexto da função. Por padrão, o contexto do repositório do OCIR está apontando para o compartimento raiz, mesmo que você siga a página de instruções na console para ser executado abaixo dos comandos do cloud shell.

    fn update context oracle.compartment-id ocid1.tenancy.oc1.....
    

    Observação: Esta parte é bastante enganosa, pois com oracle.compartment-id, as pessoas acham que essa propriedade é para a função e o OCIR. No entanto, temos uma propriedade separada para o OCIR, que é image-compartment-id. Portanto, se você estiver usando um compartimento nomeado para executar sua função e armazenar sua imagem, certifique-se de que ambos os IDs de compartimento estejam explicitamente definidos com os seguintes comandos do OCI Cloud Shell. A política apropriada do OCI IAM também deve ser configurada para permitir as ações entre o OCIR e a função também se forem de compartimentos nomeados diferentes.

    fn update context oracle.image-compartment-id <compartment-ocid>
    fn update context oracle.compartment-id <compartment-ocid>
    

    Caso isso não seja feito corretamente, você encontrará erros de 403 com fio e, como você pode nem estar ciente do image-compartment-id, é difícil encontrar uma pista.

  2. A configuração da função para usar o OCIR enquanto o OCI Cloud Shell é iniciado em um ambiente de rede acessível a docker.io, pois devemos aplicar APIs do docker para processar a imagem e, geralmente, uma rede de serviço do OCI não permitirá que você obtenha acesso. Sugerimos que você use a rede pública para implantação de contêiner se estiver usando o OCI Cloud Shell.

    Para obter mais informações, consulte Funções: Começar a usar o Cloud Shell.

  3. Outro bloqueador potencial aqui é quando você está tentando passar a mensagem da fila para as entradas da função. Várias referências podem ser encontradas em outros artigos sobre como transmitir a variável, mas na verdade é tão simples quanto inserir o json e recebê-lo no objeto data no código Python.

    Observação: Evite usar o tipo Javascript de json com o uso de aspas simples ou sem aspas, pois, por enquanto, apenas a sintaxe estrita poderia ser reconhecida pelo OCI Queue.

    {"name":"John"}
    

Confirmações

Mais Recursos de Aprendizagem

Explore outros laboratórios em docs.oracle.com/learn ou acesse mais conteúdo de aprendizado gratuito no canal Oracle Learning YouTube. Além disso, visite education.oracle.com/learning-explorer para se tornar um Oracle Learning Explorer.

Para obter a documentação do produto, visite o Oracle Help Center.