Bibliothèque de client Azure Confidential Ledger pour Python - version 1.1.1

Azure Confidential Ledger fournit un service de journalisation dans un registre immuable et inviolable. Dans le cadre du portefeuille d’informatique confidentielle Azure , Azure Confidential Ledger s’exécute dans des environnements d’exécution sécurisés basés sur le matériel, également appelés enclaves. Il s’appuie sur l’infrastructure de consortium confidentiel de Microsoft Research.

| Code sourcePackage (PyPI) | Package (Conda) | Documentation de référence sur les | APIDocumentation produit

Prise en main

Installer des packages

Installez azure-confidentialledger et azure-identity avec pip :

pip install azure-identity azure-confidentialledger

azure-identity est utilisé pour l’authentification Azure Active Directory, comme illustré ci-dessous.

Prérequis

  • Un abonnement Azure
  • Python 3.6 ou version ultérieure
  • Une instance en cours d’exécution du Registre confidentiel Azure.
  • Un utilisateur inscrit dans le registre confidentiel, généralement affecté lors de la création des ressources ARM , avec Administrator des privilèges.

Authentifier le client

Utilisation d’Azure Active Directory

Ce document illustre l’utilisation de DefaultAzureCredential pour s’authentifier auprès du registre confidentiel via Azure Active Directory. Toutefois, ConfidentialLedgerClient accepte toutes les informations d’identification azure-identity . Pour plus d’informations sur d’autres informations d’identification, consultez la documentation azure-identity .

Utilisation d’un certificat client

En guise d’alternative à Azure Active Directory, les clients peuvent choisir d’utiliser un certificat client pour s’authentifier via TLS mutuel. azure.confidentialledger.ConfidentialLedgerCertificateCredential peut être utilisé à cette fin.

Créer un client

DefaultAzureCredential gère automatiquement la plupart des scénarios de client du Kit de développement logiciel (SDK) Azure. Pour commencer, définissez des variables d’environnement pour l’identité AAD inscrite auprès de votre registre confidentiel.

export AZURE_CLIENT_ID="generated app id"
export AZURE_CLIENT_SECRET="random password"
export AZURE_TENANT_ID="tenant id"

Ensuite, DefaultAzureCredential sera en mesure d’authentifier le ConfidentialLedgerClient.

La construction du client nécessite également l’URL et l’ID de votre registre confidentiel, que vous pouvez obtenir à partir d’Azure CLI ou du portail Azure. Une fois ces valeurs récupérées, remplacez les instances de "my-ledger-id" et "https://my-ledger-id.confidential-ledger.azure.com" dans les exemples ci-dessous. Vous devrez peut-être également remplacer "https://identity.confidential-ledger.core.azure.com" par le nom d’hôte de dans identityServiceUri la description ARM de votre registre.

Étant donné que les registres confidentiels utilisent des certificats auto-signés de manière sécurisée générés et stockés dans une enclave, le certificat de signature de chaque registre confidentiel doit d’abord être récupéré à partir du service d’identité de registre confidentiel.

from azure.confidentialledger import ConfidentialLedgerClient
from azure.confidentialledger.certificate import ConfidentialLedgerCertificateClient
from azure.identity import DefaultAzureCredential

identity_client = ConfidentialLedgerCertificateClient()
network_identity = identity_client.get_ledger_identity(
    ledger_id="my-ledger-id"
)

ledger_tls_cert_file_name = "ledger_certificate.pem"
with open(ledger_tls_cert_file_name, "w") as cert_file:
    cert_file.write(network_identity["ledgerTlsCertificate"])

credential = DefaultAzureCredential()
ledger_client = ConfidentialLedgerClient(
    endpoint="https://my-ledger-id.confidential-ledger.azure.com",
    credential=credential,
    ledger_certificate_path=ledger_tls_cert_file_name
)

De manière pratique, le ConfidentialLedgerClient constructeur extrait le certificat TLS du registre (et l’écrit dans le fichier spécifié) s’il est fourni avec un fichier inexistant. L’utilisateur est responsable de la suppression du fichier créé en fonction des besoins.

from azure.confidentialledger import ConfidentialLedgerClient
from azure.identity import DefaultAzureCredential

credential = DefaultAzureCredential()
ledger_client = ConfidentialLedgerClient(
    endpoint="https://my-ledger-id.confidential-ledger.azure.com",
    credential=credential,
    ledger_certificate_path="ledger_certificate.pem"
)

# The ledger TLS certificate is written to `ledger_certificate.pem`.

Pour indiquer clairement qu’un fichier est utilisé pour le certificat TLS du registre, les exemples suivants écrivent explicitement le certificat TLS du registre dans un fichier.

Concepts clés

Entrées et transactions de registre

Chaque écriture dans Azure Confidential Ledger génère une entrée de registre immuable dans le service. Les écritures, également appelées transactions, sont identifiées de manière unique par des ID de transaction qui s’incrémentent à chaque écriture. Une fois écrites, les entrées de registre peuvent être récupérées à tout moment.

Collections

Bien que la plupart des cas d’usage n’impliquent qu’une seule collection par registre confidentiel, nous fournissons la fonctionnalité id de collection au cas où des groupes de données sémantiquement ou logiquement différents doivent être stockés dans le même registre confidentiel.

Les entrées de registre sont récupérées par leur collectionId. Le registre confidentiel suppose toujours une constante, déterminée par collectionId le service, pour les entrées écrites sans collectionId spécifié.

Utilisateurs

Les utilisateurs sont gérés directement avec le registre confidentiel au lieu d’Azure. Les utilisateurs peuvent être basés sur AAD, identifiés par leur ID d’objet AAD, ou basés sur un certificat, identifiés par leur empreinte de certificat PEM.

Receipts

Pour appliquer les garanties d’intégrité des transactions, un registre confidentiel Azure utilise une structure de données [arborescence Merkle][merkle_tree_wiki] pour enregistrer le hachage de tous les blocs de transactions ajoutés au registre immuable. Une fois qu’une transaction d’écriture est validée, les utilisateurs du registre confidentiel Azure peuvent obtenir une preuve Merkle de chiffrement, ou reçu, sur l’entrée produite dans un registre confidentiel pour vérifier que l’opération d’écriture a été correctement enregistrée. Un reçu de transaction d’écriture est la preuve que le système a validé la transaction correspondante. Il peut être utilisé pour vérifier que l’entrée a bien été ajoutée au registre.

Reportez-vous à l’article suivant pour plus d’informations sur les reçus de transaction d’écriture de registre confidentiel Azure.

Vérification des reçus

Après avoir obtenu un reçu pour une transaction en écriture, les utilisateurs d’Azure Confidential Ledger peuvent vérifier le contenu du reçu extrait à l’aide d’un algorithme de vérification. La réussite de la vérification est la preuve que l’opération d’écriture associée au reçu a été correctement ajoutée au registre immuable.

Reportez-vous à l’article suivant pour plus d’informations sur le processus de vérification des reçus de transaction d’écriture Azure Confidential Ledger.

Revendications d’application

Les applications Azure Confidential Ledger peuvent joindre des données arbitraires, appelées revendications d’application, pour les transactions en écriture. Ces revendications représentent les actions exécutées pendant une opération d’écriture. Lorsqu’elle est jointe à une transaction, la synthèse SHA-256 de l’objet de revendications est incluse dans le registre et validée dans le cadre de la transaction d’écriture. Cela garantit que le digest est signé sur place et qu’il ne peut pas être falsifié.

Plus tard, les revendications d’application peuvent être révélées sous leur forme non digérée dans la charge utile de reçu correspondant à la même transaction où elles ont été ajoutées. Cela permet aux utilisateurs de tirer parti des informations contenues dans le reçu pour calculer à nouveau la même synthèse de revendications qui a été attachée et connectée par le registre confidentiel Azure instance pendant la transaction. La synthèse de revendications peut être utilisée dans le cadre du processus de vérification du reçu de transaction en écriture. Cela permet aux utilisateurs de vérifier entièrement l’authenticité des revendications enregistrées.

Pour plus d’informations sur le format des revendications d’application et l’algorithme de calcul digest, consultez les liens suivants :

Pour plus d’informations sur les revendications de l’application CCF, reportez-vous aux pages de documentation CCF suivantes :

Informatique confidentielle

L’informatique confidentielle Azure vous permet d’isoler et de protéger vos données pendant leur traitement dans le cloud. Azure Confidential Ledger s’exécute sur des machines virtuelles Azure Confidential Computing, offrant ainsi une protection renforcée des données avec le chiffrement des données en cours d’utilisation.

Infrastructure de consortium confidentiel

Azure Confidential Ledger est basé sur l’infrastructure CCF (Confidential Consortium Framework) open source de Microsoft Research. Sous CCF, les demandes sont gérées par un consortium de membres qui ont la possibilité de soumettre des propositions pour modifier et régir le fonctionnement de la demande. Dans Azure Confidential Ledger, Microsoft Azure possède une identité de membre d’opérateur qui lui permet d’effectuer des actions de gouvernance et de maintenance telles que le remplacement de nœuds défectueux dans le registre confidentiel et la mise à niveau du code d’enclave.

Exemples

Cette section contient des extraits de code couvrant les tâches courantes, notamment :

Ajouter une entrée

Les données qui doivent être stockées de manière immuable de manière inviolable peuvent être enregistrées dans Azure Confidential Ledger en ajoutant une entrée au registre.

Étant donné que le registre confidentiel est un système distribué, de rares défaillances temporaires peuvent entraîner la perte d’écritures. Pour les entrées qui doivent être conservées, il est conseillé de vérifier que l’écriture est devenue durable. Pour les écritures moins importantes où un débit client plus élevé est préféré, l’étape d’attente peut être ignorée.

from azure.confidentialledger import ConfidentialLedgerClient
from azure.confidentialledger.certificate import ConfidentialLedgerCertificateClient
from azure.identity import DefaultAzureCredential

identity_client = ConfidentialLedgerCertificateClient()
network_identity = identity_client.get_ledger_identity(
    ledger_id="my-ledger-id"
)

ledger_tls_cert_file_name = "ledger_certificate.pem"
with open(ledger_tls_cert_file_name, "w") as cert_file:
    cert_file.write(network_identity["ledgerTlsCertificate"])

credential = DefaultAzureCredential()
ledger_client = ConfidentialLedgerClient(
    endpoint="https://my-ledger-id.confidential-ledger.azure.com",
    credential=credential,
    ledger_certificate_path=ledger_tls_cert_file_name
)

post_entry_result = ledger_client.create_ledger_entry(
        {"contents": "Hello world!"}
    )
transaction_id = post_entry_result["transactionId"]

wait_poller = ledger_client.begin_wait_for_commit(transaction_id)
wait_poller.wait()
print(f'Ledger entry at transaction id {transaction_id} has been committed successfully')

Le client peut également attendre la validation lors de l’écriture d’une entrée de registre.

from azure.confidentialledger import ConfidentialLedgerClient
from azure.confidentialledger.certificate import ConfidentialLedgerCertificateClient
from azure.identity import DefaultAzureCredential

identity_client = ConfidentialLedgerCertificateClient()
network_identity = identity_client.get_ledger_identity(
    ledger_id="my-ledger-id"
)

ledger_tls_cert_file_name = "ledger_certificate.pem"
with open(ledger_tls_cert_file_name, "w") as cert_file:
    cert_file.write(network_identity["ledgerTlsCertificate"])

credential = DefaultAzureCredential()
ledger_client = ConfidentialLedgerClient(
    endpoint="https://my-ledger-id.confidential-ledger.azure.com",
    credential=credential,
    ledger_certificate_path=ledger_tls_cert_file_name
)

post_poller = ledger_client.begin_create_ledger_entry(
    {"contents": "Hello world again!"}
)
new_post_result = post_poller.result()
print(
    'The new ledger entry has been committed successfully at transaction id '
    f'{new_post_result["transactionId"]}'
)

Récupération des entrées de registre

L’obtention d’entrées de registre antérieures à la dernière peut prendre un certain temps, car le service charge les entrées historiques. Un polleur est donc fourni.

Les entrées de registre sont récupérées par collection. La valeur retournée est la valeur contenue dans la collection spécifiée au point dans le temps identifié par l’ID de transaction.

from azure.confidentialledger import ConfidentialLedgerClient
from azure.confidentialledger.certificate import ConfidentialLedgerCertificateClient
from azure.identity import DefaultAzureCredential

identity_client = ConfidentialLedgerCertificateClient()
network_identity = identity_client.get_ledger_identity(
    ledger_id="my-ledger-id"
)

ledger_tls_cert_file_name = "ledger_certificate.pem"
with open(ledger_tls_cert_file_name, "w") as cert_file:
    cert_file.write(network_identity["ledgerTlsCertificate"])

credential = DefaultAzureCredential()
ledger_client = ConfidentialLedgerClient(
    endpoint="https://my-ledger-id.confidential-ledger.azure.com",
    credential=credential,
    ledger_certificate_path=ledger_tls_cert_file_name
)

post_poller = ledger_client.begin_create_ledger_entry(
    {"contents": "Original hello"}
)
post_result = post_poller.result()

post_transaction_id = post_result["transactionId"]

latest_entry = ledger_client.get_current_ledger_entry()
print(
    f'Current entry (transaction id = {latest_entry["transactionId"]}) '
    f'in collection {latest_entry["collectionId"]}: {latest_entry["contents"]}'
)

post_poller = ledger_client.begin_create_ledger_entry(
    {"contents": "Hello!"}
)
post_result = post_poller.result()

get_entry_poller = ledger_client.begin_get_ledger_entry(post_transaction_id)
older_entry = get_entry_poller.result()
print(
    f'Contents of {older_entry["entry"]["collectionId"]} at {post_transaction_id}: {older_entry["entry"]["contents"]}'
)

Création d’une requête à intervalles

Les entrées de registre peuvent être récupérées sur une plage d’ID de transaction. Les entrées sont uniquement retournées à partir de la collection par défaut ou spécifiée.

from azure.confidentialledger import ConfidentialLedgerClient
from azure.confidentialledger.certificate import ConfidentialLedgerCertificateClient
from azure.identity import DefaultAzureCredential

identity_client = ConfidentialLedgerCertificateClient()
network_identity = identity_client.get_ledger_identity(
    ledger_id="my-ledger-id"
)

ledger_tls_cert_file_name = "ledger_certificate.pem"
with open(ledger_tls_cert_file_name, "w") as cert_file:
    cert_file.write(network_identity["ledgerTlsCertificate"])

credential = DefaultAzureCredential()
ledger_client = ConfidentialLedgerClient(
    endpoint="https://my-ledger-id.confidential-ledger.azure.com",
    credential=credential,
    ledger_certificate_path=ledger_tls_cert_file_name
)

post_poller = ledger_client.begin_create_ledger_entry(
    {"contents": "First message"}
)
first_transaction_id = post_poller.result()["transactionId"]

for i in range(10):
    ledger_client.create_ledger_entry(
        {"contents": f"Message {i}"}
    )

post_poller = ledger_client.begin_create_ledger_entry(
    {"contents": "Last message"}
)
last_transaction_id = post_poller.result()["transactionId"]

ranged_result = ledger_client.list_ledger_entries(
    from_transaction_id=first_transaction_id,
    to_transaction_id=last_transaction_id,
)
for entry in ranged_result:
    print(f'Contents at {entry["transactionId"]}: {entry["contents"]}')

Gestion des utilisateurs

Les utilisateurs disposant Administrator de privilèges peuvent gérer les utilisateurs du registre confidentiel directement avec le registre confidentiel lui-même. Les rôles disponibles sont Reader (lecture seule), Contributor (lecture et écriture) et Administrator (lecture, écriture et ajout ou suppression d’utilisateurs).

from azure.confidentialledger import ConfidentialLedgerClient
from azure.confidentialledger.certificate import ConfidentialLedgerCertificateClient
from azure.identity import DefaultAzureCredential

identity_client = ConfidentialLedgerCertificateClient()
network_identity = identity_client.get_ledger_identity(
    ledger_id="my-ledger-id"
)

ledger_tls_cert_file_name = "ledger_certificate.pem"
with open(ledger_tls_cert_file_name, "w") as cert_file:
    cert_file.write(network_identity["ledgerTlsCertificate"])

credential = DefaultAzureCredential()
ledger_client = ConfidentialLedgerClient(
    endpoint="https://my-ledger-id.confidential-ledger.azure.com",
    credential=credential,
    ledger_certificate_path=ledger_tls_cert_file_name
)

user_id = "some AAD object id"
user = ledger_client.create_or_update_user(
    user_id, {"assignedRole": "Contributor"}
)
# A client may now be created and used with AAD credentials (i.e. AAD-issued JWT tokens) for the user identified by `user_id`.

user = ledger_client.get_user(user_id)
assert user["userId"] == user_id
assert user["assignedRole"] == "Contributor"

ledger_client.delete_user(user_id)

# For a certificate-based user, their user ID is the fingerprint for their PEM certificate.
user_id = "PEM certificate fingerprint"
user = ledger_client.create_or_update_user(
    user_id, {"assignedRole": "Reader"}
)

user = ledger_client.get_user(user_id)
assert user["userId"] == user_id
assert user["assignedRole"] == "Reader"

ledger_client.delete_user(user_id)

Utilisation de l’authentification par certificat

Les clients peuvent s’authentifier avec un certificat client dans le protocole TLS mutuel au lieu d’un jeton Azure Active Directory. ConfidentialLedgerCertificateCredential est fourni pour ces clients.

from azure.confidentialledger import (
    ConfidentialLedgerCertificateCredential,
    ConfidentialLedgerClient,
)
from azure.confidentialledger.certificate import ConfidentialLedgerCertificateClient

identity_client = ConfidentialLedgerCertificateClient()
network_identity = identity_client.get_ledger_identity(
    ledger_id="my-ledger-id"
)

ledger_tls_cert_file_name = "ledger_certificate.pem"
with open(ledger_tls_cert_file_name, "w") as cert_file:
    cert_file.write(network_identity["ledgerTlsCertificate"])

credential = ConfidentialLedgerCertificateCredential(
    certificate_path="Path to user certificate PEM file"
)
ledger_client = ConfidentialLedgerClient(
    endpoint="https://my-ledger-id.confidential-ledger.azure.com",
    credential=credential,
    ledger_certificate_path=ledger_tls_cert_file_name
)

Vérifier les reçus de transaction écrite

Les clients peuvent tirer parti de la bibliothèque de vérification des reçus dans le Kit de développement logiciel (SDK) pour vérifier les reçus de transaction en écriture émis par des instances Azure Confidential Legder. L’utilitaire peut être utilisé pour vérifier entièrement les reçus hors connexion, car l’algorithme de vérification n’a pas besoin d’être connecté à un registre confidentiel ou à tout autre service Azure.

Une fois qu’une nouvelle entrée a été ajoutée au registre (reportez-vous à cet exemple), il est possible d’obtenir un reçu pour la transaction d’écriture validée.

from azure.confidentialledger import ConfidentialLedgerClient
from azure.confidentialledger.certificate import ConfidentialLedgerCertificateClient
from azure.identity import DefaultAzureCredential

# Replace this with the Confidential Ledger ID 
ledger_id = "my-ledger-id"

# Setup authentication
credential = DefaultAzureCredential()

# Create a Ledger Certificate client and use it to
# retrieve the service identity for our ledger
identity_client = ConfidentialLedgerCertificateClient()
network_identity = identity_client.get_ledger_identity(
    ledger_id=ledger_id
)

# Save ledger service certificate into a file for later use
ledger_tls_cert_file_name = "ledger_certificate.pem"
with open(ledger_tls_cert_file_name, "w") as cert_file:
    cert_file.write(network_identity["ledgerTlsCertificate"])

# Create Confidential Ledger client
ledger_client = ConfidentialLedgerClient(
    endpoint=f"https://{ledger_id}.confidential-ledger.azure.com",
    credential=credential,
    ledger_certificate_path=ledger_tls_cert_file_name
)

# The method begin_get_receipt returns a poller that
# we can use to wait for the receipt to be available for retrieval 
get_receipt_poller = ledger_client.begin_get_receipt(transaction_id)
get_receipt_result = get_receipt_poller.result()

print(f"Write receipt for transaction id {transaction_id} was successfully retrieved: {get_receipt_result}")

Après avoir récupéré un reçu pour une transaction d’écriture, il est possible d’appeler la verify_receipt fonction pour vérifier que le reçu est valide. La fonction peut accepter une liste facultative de revendications d’application à vérifier par rapport au condensé des revendications de reçu.

from azure.confidentialledger.receipt import (
    verify_receipt,
)

# Read contents of service certificate file saved in previous step.
with open(ledger_tls_cert_file_name, "r") as service_cert_file:
    service_cert_content = service_cert_file.read()

# Optionally read application claims, if any
application_claims = get_receipt_result.get("applicationClaims", None) 

try:
    # Verify the contents of the receipt.
    verify_receipt(get_receipt_result["receipt"], service_cert_content, application_claims=application_claims)
    print(f"Receipt for transaction id {transaction_id} successfully verified")
except ValueError:
    print(f"Receipt verification for transaction id {transaction_id} failed")

Un exemple complet de programme Python qui montre comment ajouter une nouvelle entrée à une instance de registre confidentiel en cours d’exécution, obtenir un reçu pour la transaction validée et vérifier le contenu du reçu se trouve sous le dossier d’exemples: get_and_verify_receipt.py.

API asynchrone

Cette bibliothèque inclut une API asynchrone complète prise en charge sur Python 3.5+. Pour l’utiliser, vous devez d’abord installer un transport asynchrone, tel que aiohttp. Pour plus d’informations, consultez la documentation azure-core .

Un client asynchrone est obtenu à partir de azure.confidentialledger.aio. Les méthodes ont les mêmes noms et signatures que le client synchrone. Vous trouverez des exemples ici.

Dépannage

Général

Les clients de registre confidentiel lèvent des exceptions définies dans azure-core. Par exemple, si vous essayez d’obtenir une transaction qui n’existe pas, ConfidentialLedgerClient déclenche ResourceNotFoundError :

from azure.core.exceptions import ResourceNotFoundError
from azure.confidentialledger import ConfidentialLedgerClient
from azure.confidentialledger.certificate import ConfidentialLedgerCertificateClient
from azure.identity import DefaultAzureCredential

identity_client = ConfidentialLedgerCertificateClient()
network_identity = identity_client.get_ledger_identity(
    ledger_id="my-ledger-id"
)

ledger_tls_cert_file_name = "ledger_certificate.pem"
with open(ledger_tls_cert_file_name, "w") as cert_file:
    cert_file.write(network_identity["ledgerTlsCertificate"])

credential = DefaultAzureCredential()
ledger_client = ConfidentialLedgerClient(
    endpoint="https://my-ledger-id.confidential-ledger.azure.com",
    credential=credential,
    ledger_certificate_path=ledger_tls_cert_file_name
)

try:
    ledger_client.begin_get_ledger_entry(
        transaction_id="10000.100000"  # Using a very high id that probably doesn't exist in the ledger if it's relatively new.
    )
except ResourceNotFoundError as e:
    print(e.message)

Journalisation

Cette bibliothèque utilise la bibliothèque de journalisation standard pour la journalisation. Les informations de base sur les sessions HTTP (URL, en-têtes, etc.) sont enregistrées au niveau INFO.

La journalisation détaillée au niveau DEBUG, y compris les corps de requête/réponse et les en-têtes non expurgés, peut être activée sur un client avec l’argument logging_enable :

import logging
import sys

from azure.confidentialledger import ConfidentialLedgerClient
from azure.confidentialledger.certificate import ConfidentialLedgerCertificateClient
from azure.identity import DefaultAzureCredential

# Create a logger for the 'azure' SDK
logger = logging.getLogger('azure')
logger.setLevel(logging.DEBUG)

# Configure a console output
handler = logging.StreamHandler(stream=sys.stdout)
logger.addHandler(handler)

identity_client = ConfidentialLedgerCertificateClient()
network_identity = identity_client.get_ledger_identity(
    ledger_id="my-ledger-id"
)

ledger_tls_cert_file_name = "ledger_certificate.pem"
with open(ledger_tls_cert_file_name, "w") as cert_file:
    cert_file.write(network_identity["ledgerTlsCertificate"])

credential = DefaultAzureCredential()

# This client will log detailed information about its HTTP sessions, at DEBUG level.
ledger_client = ConfidentialLedgerClient(
    endpoint="https://my-ledger-id.confidential-ledger.azure.com",
    credential=credential,
    ledger_certificate_path=ledger_tls_cert_file_name,
    logging_enable=True,
)

De la même façon, logging_enable peut activer la journalisation détaillée pour une seule opération, même quand elle n’est pas activée pour le client :

ledger_client.get_current_ledger_entry(logging_enable=True)

Étapes suivantes

Autres exemples de code

Ces exemples de code montrent des opérations de scénario courantes avec la bibliothèque cliente de registre confidentiel Azure.

Scénarios courants

Scénarios avancés

Documentation complémentaire

Pour obtenir une documentation plus complète sur le registre confidentiel Azure, consultez la documentation de référence sur les API. Vous pouvez également en savoir plus sur l’infrastructure de consortium confidentiel open source de Microsoft Research.

Contribution

Ce projet accepte les contributions et les suggestions. La plupart des contributions vous demandent d’accepter un contrat de licence de contribution (CLA) déclarant que vous avez le droit de nous accorder, et que vous nous accordez réellement, les droits d’utilisation de votre contribution. Pour plus d’informations, visitez https://cla.microsoft.com.

Quand vous envoyez une demande de tirage (pull request), un bot CLA détermine automatiquement si vous devez fournir un contrat CLA et agrémenter la demande de tirage de façon appropriée (par exemple, avec une étiquette ou un commentaire). Suivez simplement les instructions fournies par le bot. Vous ne devez effectuer cette opération qu’une seule fois sur tous les dépôts utilisant notre contrat CLA.

Ce projet a adopté le Code de conduite Open Source de Microsoft. Pour plus d'informations, consultez la FAQ du Code de conduite ou contactez opencode@microsoft.com pour toute question ou commentaire supplémentaire.