Sdílet prostřednictvím


Klientská knihovna Azure Confidential Ledger pro Python – verze 1.1.1

Azure Confidential Ledger poskytuje službu pro protokolování do neměnné hlavní knihy odolné proti neoprávněné manipulaci. Jako součást portfolia důvěrných výpočetních operací Azure běží služba Azure Confidential Ledger v zabezpečených hardwarových důvěryhodných spouštěcích prostředích, označovaných také jako enklávy. Je postaven na důvěrném konsorciu Microsoft Research Framework.

Zdrojový kód | Balíček (PyPI) | Balíček (Conda) | Referenční dokumentace k | rozhraní APIDokumentace k produktu

Začínáme

Instalace balíčků

Nainstalujte azure-confidentialledger a azure-identity pomocí pipu:

pip install azure-identity azure-confidentialledger

Azure-identity se používá k ověřování Azure Active Directory, jak je znázorněno níže.

Požadavky

  • Předplatné Azure
  • Python 3.6 nebo novější
  • Spuštěná instance služby Azure Confidential Ledger.
  • Registrovaný uživatel v důvěrném registru, který se obvykle přiřadí při vytváření prostředku ARM , s oprávněními Administrator .

Ověření klienta

Použití Azure Active Directory

Tento dokument ukazuje použití DefaultAzureCredential k ověření ve službě Confidential Ledger prostřednictvím Azure Active Directory. Akceptuje ConfidentialLedgerClient ale všechny přihlašovací údaje azure-identity . Další informace o dalších přihlašovacích údaji najdete v dokumentaci k azure-identity .

Použití klientského certifikátu

Jako alternativu k Azure Active Directory se klienti můžou rozhodnout použít klientský certifikát k ověřování prostřednictvím vzájemného protokolu TLS. azure.confidentialledger.ConfidentialLedgerCertificateCredential k tomuto účelu.

Vytvoření klienta

DefaultAzureCredential automaticky zpracuje většinu klientských scénářů sady Azure SDK. Začněte nastavením proměnných prostředí pro identitu AAD zaregistrovanou ve službě Confidential Ledger.

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

DefaultAzureCredential Pak bude moct ověřit .ConfidentialLedgerClient

Sestavení klienta také vyžaduje adresu URL a ID vaší služby Confidential Ledger, které můžete získat z Azure CLI nebo webu Azure Portal. Po načtení těchto hodnot nahraďte instance "my-ledger-id" a "https://my-ledger-id.confidential-ledger.azure.com" v následujících příkladech. Možná také budete muset nahradit "https://identity.confidential-ledger.core.azure.com" názvem hostitele z identityServiceUri názvu arm v popisu registru.

Protože důvěrné knihy používají certifikáty podepsané svým držitelem bezpečně generované a uložené v enklávě, podpisový certifikát pro každou důvěrnou ledger musí být nejprve načten ze služby Identita důvěrné knihy.

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
)

Konstruktor pohodlně ConfidentialLedgerClient načte certifikát TLS registru (a zapíše ho do zadaného souboru), pokud je k dispozici neexistující soubor. Uživatel zodpovídá za odebrání vytvořeného souboru podle potřeby.

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`.

Aby bylo jasné, že se pro certifikát TLS registru používá soubor, následující příklady explicitně zapíšou certifikát TLS registru do souboru.

Klíčové koncepty

Položky a transakce hlavní knihy

Každý zápis do služby Azure Confidential Ledger vygeneruje neměnnou položku registru. Zápisy, označované také jako transakce, jsou jednoznačně identifikovány ID transakcí, které se s každým zápisem navyšují. Po zápisu mohou být položky registru kdykoli načteny.

Kolekce

I když většina případů použití zahrnuje jenom jednu kolekci na confidential ledger, poskytujeme funkci ID kolekce pro případ, že ve stejné důvěrné knize musí být uloženy sémanticky nebo logicky různé skupiny dat.

Položky hlavní knihy se načítají pomocí .collectionId Confidential Ledger bude vždy předpokládat konstantní službu určenou collectionId pro položky zapsané bez zadané hodnoty collectionId .

Uživatelé

Uživatelé jsou spravováni přímo pomocí služby Confidential Ledger, nikoli prostřednictvím Azure. Uživatelé můžou být založeni na AAD, identifikovaní svým ID objektu AAD nebo identifikovaní pomocí otisku prstu certifikátu PEM.

Účtenky

Aby bylo možné vynutit záruky integrity transakcí, azure Confidential Ledger používá [Merkleův strom][merkle_tree_wiki] datovou strukturu k záznamu hodnoty hash všech bloků transakcí, které jsou připojeny k neměnné hlavní knize. Po potvrzení transakce zápisu můžou uživatelé služby Azure Confidential Ledger získat kryptografický Merkleův důkaz (potvrzení) přes položku vytvořenou v důvěrném registru, aby ověřili, že operace zápisu byla správně uložena. Potvrzení transakce zápisu je důkazem, že systém potvrdil odpovídající transakci, a lze jej použít k ověření, že položka byla účinně připojena do hlavní knihy.

Další informace o potvrzeních transakcí zápisu do služby Azure Confidential Ledger najdete v následujícím článku .

Ověření příjmu

Po obdržení potvrzení o transakci zápisu můžou uživatelé služby Azure Confidential Ledger ověřit obsah načteného potvrzení pomocí ověřovacího algoritmu. Úspěch ověření je důkazem, že operace zápisu přidružená k potvrzení byla správně připojena do neměnné hlavní knihy.

Další informace o procesu ověřování potvrzení transakcí zápisu do služby Azure Confidential Ledger najdete v následujícím článku .

Deklarace identity aplikací

Aplikace Azure Confidential Ledger můžou k zápisu transakcí připojit libovolná data, označovaná jako deklarace identity aplikací. Tyto deklarace identity představují akce prováděné během operace zápisu. Při připojení k transakci je algoritmus hash SHA-256 objektu deklarací zahrnut do hlavní knihy a potvrzen jako součást transakce zápisu. Tím je zaručeno, že je přehled podepsaný na místě a nebude možné s tímto algoritmem manipulovat.

Později mohou být deklarace identity aplikace odhaleny v jejich netvrzené podobě v datové části příjmu odpovídající stejné transakci, do které byly přidány. To umožňuje uživatelům využít informace v potvrzení k opětovnému výpočtu stejného přehledu deklarací identity, který byl připojen a podepsán instancí služby Azure Confidential Ledger během transakce. Digest deklarací identity lze použít jako součást procesu ověřování potvrzení transakce zápisu, což uživatelům poskytuje offline způsob, jak plně ověřit pravost zaznamenaných deklarací.

Další podrobnosti o formátu deklarací identity aplikace a výpočetním algoritmu digest najdete na následujících odkazech:

Další informace o deklaracích aplikací CCF najdete na následujících stránkách dokumentace CCF:

Důvěrné výpočetní operace

Důvěrné výpočetní operace Azure umožňují izolovat a chránit vaše data během jejich zpracování v cloudu. Služba Azure Confidential Ledger běží na virtuálních počítačích Azure Confidential Computing a poskytuje tak silnější ochranu dat s šifrováním užitých dat.

Důvěrný rámec konsorcia

Služba Azure Confidential Ledger je postavená na opensourcové architektuře Confidential Consortium Framework (CCF) společnosti Microsoft Research. V rámci CCF jsou aplikace spravovány konsorciem členů s možností předkládat návrhy na úpravy a řízení provozu aplikace. Ve službě Azure Confidential Ledger vlastní Microsoft Azure identitu člena operátora, která jí umožňuje provádět akce zásad správného řízení a údržby, jako je nahrazení uzlů, které nejsou v pořádku, v důvěrném registru a upgrade kódu enklávy.

Příklady

Tato část obsahuje fragmenty kódu, které pokrývají běžné úlohy, mezi které patří:

Připojit položku

Data, která musí být uložena neměnně způsobem, který je odolný proti neoprávněné manipulaci, je možné uložit do služby Azure Confidential Ledger tak, že k hlavní knize připojíte položku.

Vzhledem k tomu, že Confidential Ledger je distribuovaný systém, můžou vzácná přechodná selhání způsobit ztrátu zápisu. U položek, které musí být zachovány, je vhodné ověřit, že zápis se stal trvalým. U méně důležitých zápisů, kde se upřednostňuje vyšší propustnost klienta, může být krok čekání vynechán.

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')

Případně může klient při zápisu položky registru čekat na potvrzení.

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"]}'
)

Načítání položek registru

Získání položek registru starších než nejnovější může nějakou dobu trvat, protože služba načítá historické položky, takže je k dispozici poller.

Položky hlavní knihy se načítají podle kolekce. Vrácená hodnota je hodnota obsažená v zadané kolekci k bodu v čase identifikovaném ID transakce.

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"]}'
)

Vytvoření dotazu s rozsahem

Položky hlavní knihy mohou být načteny v rozsahu ID transakcí. Položky budou vráceny pouze z výchozí nebo zadané kolekce.

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"]}')

Správa uživatelů

Uživatelé s oprávněními Administrator můžou spravovat uživatele confidential ledger přímo pomocí samotné služby Confidential Ledger. Dostupné role jsou Reader (jen pro čtení), Contributor (čtení a zápis) a Administrator (čtení, zápis a přidání nebo odebrání uživatelů).

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)

Použití ověřování certifikátů

Klienti se můžou ověřovat pomocí klientského certifikátu ve vzájemném protokolu TLS místo pomocí tokenu Azure Active Directory. ConfidentialLedgerCertificateCredential je pro tyto klienty k dispozici.

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
)

Ověření potvrzení transakce zápisu

Klienti můžou využít knihovnu ověření potvrzení v sadě SDK k ověření potvrzení o zápisu transakcí vystavených instancemi Azure Confidential Legder. Nástroj lze použít k úplnému ověření účtenek offline, protože ověřovací algoritmus nevyžaduje připojení k důvěrné registru nebo jiné službě Azure.

Po připojení nové položky k registru (viz tento příklad), je možné získat potvrzení o potvrzené transakci zápisu.

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}")

Po načtení potvrzení o transakci zápisu je možné volat verify_receipt funkci a ověřit tak, že potvrzení je platné. Funkce může přijmout volitelný seznam deklarací identity aplikace k ověření v hodnotě digest deklarací deklarací identity potvrzení.

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")

Úplný ukázkový program Pythonu, který ukazuje, jak připojit novou položku ke spuštěné instanci Confidential Ledger, získat potvrzení o potvrzené transakci a ověřit obsah potvrzení najdete ve složce samples : get_and_verify_receipt.py.

Asynchronní rozhraní API

Tato knihovna obsahuje kompletní asynchronní rozhraní API podporované v Pythonu 3.5 a novějším. Abyste ho mohli používat, musíte nejprve nainstalovat asynchronní přenos, například aiohttp. Další informace najdete v dokumentaci k azure-core .

Asynchronní klient se získá z azure.confidentialledger.aio. Metody mají stejné názvy a podpisy jako synchronní klient. Ukázky najdete tady.

Poradce při potížích

Obecné

Klienti Confidential Ledger vyvolávají výjimky definované v azure-core. Pokud se například pokusíte získat transakci, která neexistuje, ConfidentialLedgerClient vyvolá chybu 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)

protokolování

Tato knihovna používá pro protokolování standardní knihovnu protokolování . Základní informace o relacích HTTP (adresy URL, hlavičky atd.) se protokolují na úrovni INFO.

Podrobné protokolování úrovně LADĚNÍ, včetně těl požadavků/odpovědí a nereagovaných hlaviček, je možné povolit na klientovi s argumentem 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,
)

Podobně logging_enable může povolit podrobné protokolování pro jednu operaci, i když není povolené pro klienta:

ledger_client.get_current_ledger_entry(logging_enable=True)

Další kroky

Další ukázkový kód

Tyto ukázky kódu ukazují běžné operace scénářů s klientskou knihovnou Azure Confidential Ledger.

Obvyklé scénáře

Pokročilé scénáře

Další dokumentace

Rozsáhlejší dokumentaci ke službě Azure Confidential Ledger najdete v referenční dokumentaci k rozhraní API. Můžete si také přečíst další informace o opensourcové architektuře důvěrného konsorcia společnosti Microsoft Research.

Přispívání

Tento projekt vítá příspěvky a návrhy. Většina příspěvků vyžaduje souhlas s licenční smlouvou s přispěvatelem (CLA), která stanoví, že máte právo udělit nám práva k používání vašeho příspěvku a skutečně tak činíte. Podrobnosti najdete tady: https://cla.microsoft.com

Při odesílání žádosti o přijetí změn robot CLA automaticky určí, jestli je potřeba poskytnout smlouvu CLA, a příslušným způsobem žádost o přijetí změn upraví (např. přidáním jmenovky nebo komentáře). Stačí postupovat podle pokynů robota. Pro všechna úložiště používající naši smlouvu CLA to stačí udělat jenom jednou.

Tento projekt přijal pravidla chování pro Microsoft Open Source. Další informace najdete v nejčastějších dotazech k pravidlům chování. V případě jakýchkoli dotazů nebo připomínek kontaktujte opencode@microsoft.com.