1
votes

Obtenir un secret depuis Azure Keyvault avec un nœud depuis une machine virtuelle Linux avec MSI

Je rencontre des problèmes pour obtenir un secret d'Azure keyvault à l'aide du package azure-keyvault à partir d'une application de nœud s'exécutant sur une machine virtuelle Linux sous azure.

J'utilise le code suivant:

msRestAzure.loginWithVmMSI({resource: 'https://vault.azure.net' });

J'obtiens une réponse 401 en appelant getSecret. Des autorisations sont définies sur la machine sur le keyvault et le MSI. Dans l'erreur que j'obtiens, il ne semble y avoir aucun en-tête d'authentification ou de jeton, bien que je vois un en-tête qui ressemble à un en-tête d'authentification sur la réponse.

Y a-t-il quelque chose qui me manque dans ma mise en œuvre?

MODIFIER: Il semble que l'exemple que j'ai partagé ici aurait fonctionné si j'avais utilisé

import * as KeyVault from 'azure-keyvault';
import * as msRestAzure from 'ms-rest-azure'

function getKeyVaultCredentials(){
    return msRestAzure.loginWithVmMSI();
}

function getKeyVaultSecret(credentials) {
    let keyVaultClient = new KeyVault.KeyVaultClient(credentials,null);
    return keyVaultClient.getSecret("my keyvault url here", 'my keyvault secret name here', "", null,null);
}

getKeyVaultCredentials().then(
    getKeyVaultSecret
).then(function (secret){
    //not getting here....
}).catch(function (err) {
    //...error handling...
});

au lieu de l'appeler sans paramètre.


2 commentaires

Je suis confus. Où demandez-vous un jeton? Vous devriez pouvoir voir votre jeton dans l'en-tête de réponse de votre requête https. Vous devez également utiliser des rappels.


@ Rthomas529 J'essaye d'utiliser le paquet azure-keyvault ... donc certaines informations me sont cachées. suggérez-vous d'utiliser simplement l'API standard avec de simples requêtes http?


3 Réponses :


2
votes

Dans votre coffre de clés, assurez-vous d'avoir ajouté le principal de service (créé automatiquement en activant le MSI) dans les Stratégies d'accès avec l'autorisation secrète correcte. Ensuite, essayez de cliquer sur Cliquez pour afficher les stratégies d'accès avancées -> choisissez l'option Activer l'accès aux machines virtuelles Azure pour le déploiement -> Enregistrer.

Voici un exemple de code, vous pouvez vérifier la partie de la récupération d'une valeur secrète.

var http = require('http');
const KeyVault = require('azure-keyvault');
const msRestAzure = require('ms-rest-azure');


var server = http.createServer(function(request, response) {
    response.writeHead(200, {"Content-Type": "text/plain"});
});

// The ms-rest-azure library allows us to login with MSI by providing the resource name. In this case the resource is Key Vault.
// For public regions the resource name is Key Vault
msRestAzure.loginWithAppServiceMSI({resource: 'https://vault.azure.net'}).then( (credentials) => {
    const keyVaultClient = new KeyVault.KeyVaultClient(credentials);

    var vaultUri = "https://" + "<YourVaultName>" + ".vault.azure.net/";

    // We're setting the Secret value here and retrieving the secret value
    keyVaultClient.setSecret(vaultUri, 'my-secret', 'test-secret-value', {})
        .then( (kvSecretBundle, httpReq, httpResponse) => {
            console.log("Secret id: '" + kvSecretBundle.id + "'.");
            return keyVaultClient.getSecret(kvSecretBundle.id, {});
        })
        .then( (bundle) => {
            console.log("Successfully retrieved 'test-secret'");
            console.log(bundle);
        })
        .catch( (err) => {
            console.log(err);
        });

    // Below code demonstrates how to retrieve a secret value

    // keyVaultClient.getSecret(vaultUri, "AppSecret", "").then(function(response){
    //     console.log(response);    
    // })
});

Pour plus de détails, vous pouvez vous référer à: Définir et récupérer un secret depuis Azure Key Vault à l'aide d'une application Web Node .


5 commentaires

J'ai remarqué que vous utilisez loginWithAppServiceMSI dans votre exemple, mais je n'ai pas d'AppService, j'ai une VM standard, ne devrais-je pas utiliser loginWithVmMSI?


@Mithir Oui, je pense que vous devriez utiliser loginWithVmMSI dans votre cas. BTW, avez-vous d'abord vérifié vos autorisations?


Je viens de mettre en œuvre l'obtention du secret avec des requêtes http simples et cela a fonctionné. Je reçois d'abord un jeton, puis j'obtiens le secret avec un en-tête d'autorisation contenant les détails du jeton - les autorisations sont donc correctes. Je préfère toujours utiliser le package mais je ne suis pas sûr de ce qui manque ...


@Mithir Pourriez-vous suivre l'exemple pour essayer? Peu importe l'utilisation du msi du service d'application ou de la vm, la logique doit être similaire.


Ok merci beaucoup ... il semble que j'ai manqué la partie ressource dans mon exemple ... Merci beaucoup!



0
votes

Vous pouvez utiliser read-azure-secrets qui récupérera tous les secrets depuis le coffre de clés azure.

Par exemple

let secretClient = require('read-azure-secrets');

async function loadKeyVaultValues() {

    let applicationID = '';
    let applicationSecret = '';
    let vaultURL = 'https://<your-key-vault-name>.vault.azure.net/';
    let secrets = await secretClient.getSecrets(applicationID, applicationSecret, vaultURL);

    secrets.forEach(secret => {
        console.log(secret);
    });

}

loadKeyVaultValues();


0 commentaires

1
votes

Cela a maintenant été simplifié dans le nouveau package @ azure / keyvault-secrets où le SecretClient peut prendre le DefaultAzureCredential du @ azure / identity package qui à son tour est suffisamment intelligent pour utiliser les détails MSI lorsqu'il est exécuté sur votre machine virtuelle, ainsi que les informations d'identification du développeur telles que VS Code ou Azure CLI dans votre environnement de développement local. Vous pouvez en savoir plus à ce sujet dans le readme for @ azure / identity

Avec cela, votre code serait simplifié en

const { SecretClient } = require("@azure/keyvault-secrets");
const { DefaultAzureCredential } = require("@azure/identity");

async function getValue(secretName, secretVersion) {
  const credential = new DefaultAzureCredential();
  const client = new SecretClient(KEY_VAULT_URI, credential);
  const secret = await client.getSecret(secretName);
  return secret.value;
}

Pour déplacer votre application de l'ancien package azure-keyvault qui est maintenant obsolète, vous pouvez voir la migration guide des nouveaux @ azure / keyvault-secrets


0 commentaires