Create and Publish Card on Cards ServicesThis guide shows how to create a user's Card with public key inside, and publish a Card on the Virgil Cards Service.Prerequisites for workInstall SDK & Setup Virgil CryptoThe Virgil Python SDK is provided as a package named virgil_sdk. The package is distributed via pip package manager.The package is available for:Python 2.7.xPython 3.xInstalling the package:The Virgil Python SDK is provided as a package named virgil_sdk. The package is distributed via Pypi package management system. To install the pip package use the command below:pip install virgil_sdkSet up a storage for Private KeysSetup a VSSKeyStorage in order to save private keys after their generation.from virgil_crypto import VirgilCrypto, PrivateKeyExporter from virgil_sdk.storage import PrivateKeyStorage # initialize Crypto library crypto = VirgilCrypto() # Generate a private key key_pair = crypto.generate_keys() private_key = key_pair.private_key # Setup PrivateKeyStorage exporter = PrivateKeyExporter() private_key_storage = PrivateKeyStorage(exporter, "YOUR_PASSWORD") # Store a private key with a name, for example Alice private_key_storage.store(private_key, "Alice") # To load Alice private key use the following code lines: loaded_private_key, loaded_additional_data = private_key_storage.load("Alice") # Delete a private key private_key_storage.delete("Alice")Set up authentication on a server side and generate a JWTCollect your Virgil developer credentialsParameterDescriptionAPP_IDID of your Application at Virgil DashboardAPI_KEY_IDA unique string value that identifies your account at the Virgil developer portalAPI_KEYA Private Key that is used to sign API calls to Virgil Services. For security, you will only be shown the API Private Key when the key is created. Don't forget to save it in a secure location for the next stepNext, you'll set up the JwtGenerator using the Virgil SDK. You'll use your API Key that was created at Virgil Dashboard. For security purposes, you have to generate JWT on your server side. Each JWT is granted access to a specific Application and has a limited lifetime that is configured by you. However, best practice is to generate JWT for the shortest amount of time feasible for your application.Here is an example of how to generate JWT:import datetime from virgil_crypto import VirgilCrypto from virgil_crypto.access_token_signer import AccessTokenSigner from virgil_sdk.jwt import JwtGenerator from virgil_sdk.utils import Utils # API_KEY (you got this Key at Virgil Dashboard) api_key_base64 = "MIGhMF0GCSqGSIb3DQEFDTBQMC8GCSqGSIb3DQEFDDAiBBC7Sg/DbNzhJ/uakTvafUMoAgIUtzAKBggqhkiG9w0CCjAdBglghkgBZQMEASoEEDunQ1yhWZoKaLaDFgjpxRwEQAFdbC8e6103lJrUhY9ahyUA8+4rTJKZCmdTlCDPvoWH/5N5kxbOvTtbxtxevI421z3gRbjAtoWkfWraSLD6gj0=" private_key_data = Utils.b64_decode(api_key_base64) # Crypto library imports a private key into a necessary format crypto = VirgilCrypto() api_key = crypto.import_private_key(private_key_data) # initialize accessTokenSigner that signs users JWTs access_token_signer = AccessTokenSigner() # use your App Credentials you got at Virgil Dashboard: app_id = "be00e10e4e1f4bf58f9b4dc85d79c77a" app_key_id = "70b447e321f3a0fd" ttl = datetime.timedelta(hours=1).seconds # setup JWT generator with necessary parameters: jwt_generator = JwtGenerator(app_id, api_key, app_key_id, ttl, access_token_signer) # generate JWT for a user # remember that you must provide each user with his unique JWT # each JWT contains unique user's identity (in this case - Alice) # identity can be any value: name, email, some id etc. identity = "Alice" alice_jwt = jwt_generator.generate_token(identity) # as result you get users JWT, it looks like this: "eyJraWQiOiI3MGI0NDdlMzIxZjNhMGZkIiwidHlwIjoiSldUIiwiYWxnIjoiVkVEUzUxMiIsImN0eSI6InZpcmdpbC1qd3Q7dj0xIn0.eyJleHAiOjE1MTg2OTg5MTcsImlzcyI6InZpcmdpbC1iZTAwZTEwZTRlMWY0YmY1OGY5YjRkYzg1ZDc5Yzc3YSIsInN1YiI6ImlkZW50aXR5LUFsaWNlIiwiaWF0IjoxNTE4NjEyNTE3fQ.MFEwDQYJYIZIAWUDBAIDBQAEQP4Yo3yjmt8WWJ5mqs3Yrqc_VzG6nBtrW2KIjP-kxiIJL_7Wv0pqty7PDbDoGhkX8CJa6UOdyn3rBWRvMK7p7Ak" # you can provide users with JWT at registration or authorization steps # Send a JWT to client-side jwt_string = alice_jwt.to_string()Set up authentication on a client side and send a JWT requestIn order to make call to Virgil Services, for example, to publish user's Card on Virgil Cards Service you need to have a JSON Web Token ("JWT"). Virgil SDKs let you use Virgil token-generation functionality without having to know how they're constructed.After a user installs Virgil SDK you'll need to set up jwtProvider for providing users with a JWT. You'll need to give your users a JWT that tells Virgil who they are and what they can do.Requests to your app server must be authorized. You can use for this task any kind of authentication, for example, Google auth.Set up JWT providerUse these lines of code to specify which JWT generation source you prefer to use in your project:from virgil_sdk.jwt.providers import CallbackJwtProvider # Get generated token from server-side def get_token_from_server(): jwt_from_server = aunthficated_query_to_server(token_context) return jwt_from_server # setup access token access_token_provider = CallbackJwtProvider(get_token_from_server)Set up Card VerifierVirgil Card Verifier helps you automatically verify signatures of a User's Card, for example when you get a Card from Virgil Cards Service.By default, VirgilCardVerifier verifies only two signatures - a Card owner and Virgil Cards Service.Set up VirgilCardVerifier with the following lines of code:from virgil_crypto.card_crypto import CardCrypto from virgil_sdk import VirgilCardVerifier from virgil_sdk.verification import VerifierCredentials, WhiteList # initialize Crypto library card_crypto = CardCrypto() your_backend_verifier_credentials = VerifierCredentials(signer="YOUR_BACKEND", public_key_base64=public_key_str) your_backend_white_list = WhiteList() your_backend_white_list.verifiers_credentials = your_backend_verifier_credentials verifier = VirgilCardVerifier(card_crypto, white_lists=[your_backend_white_list])Set up Cards Manager to manage public keysWith Cards Manager you can:specify an access Token (JWT) Provider.specify a Crypto Library that you’re planning to use for crypto operations.specify a Card Verifier used to verify signatures of your users, your App Server, Virgil Services (optional).Set up CryptoUse the following lines of code to specify which crypto library (Virgil or your own) you prefer to use in your project:from virgil_crypto.card_crypto import CardCrypto # initialize Crypto Library card_crypto = CardCrypto()Initialize Card ManagerUse the following lines of code to set up the Card Manager:from virgil_sdk import CardManager, VirgilCardVerifier # initialize card_manager and specify access_token_provider, card_verifier card_manager = CardManager( card_crypto, access_token_provider, card_verifier )You cannot change a Card's content after it's published because it's signed with the owner's Private Key.Create CardOnce a Virgil SDK and a Crypto Library are ready we can generate a Private Key and create a user's Card. Use the following lines of code to create and publish a user's Card (without a signature from your app server):from virgil_crypto import VirgilCrypto from virgil_sdk.storage import PrivateKeyStorage crypto = VirgilCrypto() # generate a key pair key_pair = crypto.generate_keys() # save Alice private key into key sotrage private_key_storage = PrivateKeyStorage() private_key_storage.store(key_pair.private_key, "Alice") # create and publish user's card with identity Alice on the Card Service card = card_manager.publish_card( identity="Alice", private_key=key_pair.private_key, public_key=key_pair.public_key )As result, a user's Card will be published on the Virgil Cards Service, where it will be available at any time. The private keys stay on a user's devices.Remember that each user can have as many Cards as he/she needs for various tasks. If you create more than one Card for a user, you can specify information about the previous Card when you create the next Card.For more information about Card structure and creation, click hereIf you want to add an additional layer of security into your Card, you can sign a Card with an additional key, for example, with the private key of your application server. Thus, you can be sure that a user's Card wasn't replaced with another one on Virgil Cards Service.