Documentation / Guides

Create your own clients

With an organisation key, your organisation creates its own clients and gets each client’s certificate in the same answer. No registration key, no email, no waiting for Knovas.

The organisation key

Knovas issues the key for your organisation. It is shown only once, when it is issued, and starts with knovas_ook_. Knovas stores only a fingerprint of it, so it cannot show you the key again: store it in your secrets manager straight away.

The key canThe key cannot
Create a client in your organisation and return its certificateOpen /secured/..., read documents, or list your clients
Renew the certificate of one of your clients, together with that client’s current private keyDo anything in another organisation

A client is one user of Knovas: a person, a machine or an installation. Every client has its own certificate and its own private space for documents. Clients do not see each other’s documents, even within one organisation.

LimitValue
Lifetime of a keyAt most one year. Knovas tells you the date.
Clients per keySet by Knovas when it issues the key (100 unless agreed otherwise). Every answer tells you how many are left (clients_left).
Events per key and hour20: clients created, certificates renewed and refused duplicates together
Active keys per organisation2, so you can switch to a new key before the old one is revoked
Keep the key secret
  • Store it in a secrets manager and send it only in the Authorization header.
  • Never put it in a web address, a request body, a log, a code repository, an email or a chat. Its knovas_ook_ prefix lets secret scanners find it.
Every use is reported

Every client created and every certificate renewed with your key sends an email to the contact Knovas named when it issued the key (otherwise to your organisation’s main contact). The email names the client id, never the key. If you get one for something you did not do, contact Knovas at once: the key may have leaked.

If the key leaks, is lost or should change

SituationWhat happens
The key leakedTell Knovas at once. Knovas revokes it, and it stops working on its next use. Clients created with it keep working, unless Knovas also withdraws their certificates; those then stop working within 45 seconds.
The key is lostKnovas cannot show it again. It revokes the lost key and issues a new one.
You want a new keyAsk Knovas for a second key, switch your systems to it, then ask Knovas to revoke the first one.

Create a client

Send POST https://api.knovas.ch/onboard_client (port 443, no client certificate) with the header Authorization: Knovas-Org-Key <your organisation key> and these fields:

FieldRequiredWhat it is
first_name, last_nameYesThe client’s name (each at most 255 characters).
emailYesThe client’s email address. It is written into the certificate, so it must be a plain address without special characters. Knovas never checks it and never writes to it.
country, city, postal_code, addressNoThe client’s own address, if it has one.
csr_pemNo, but recommendedA signing request for a key you created (see below).
allow_duplicateNotrue creates a second client with an email address that a client of your organisation already has.

Any other field is refused (400 UNKNOWN_FIELD). You never name an organisation or a client id: the organisation always comes from the key, and Knovas chooses the client id (400 FORBIDDEN_FIELD).

Who makes the private key

With csr_pem (recommended)Without csr_pem
Who makes the private keyYou, on the client’s machineKnovas, for this one answer
What the answer carriesThe certificateThe certificate and the private key
If the answer is lostRetry with the same Idempotency-Key and you get the certificateThe private key is gone. Create a new client

Either way Knovas writes the certificate’s details itself: the client id, your organisation’s name and the email. From a signing request it takes only the public key. Accepted keys: RSA with at least 2048 bits, or EC on the P-256 or P-384 curve. Knovas never stores a private key it makes. The example creates the key on this machine and sends only a signing request:

umask 077                                  # new files are readable by you only
IDEMPOTENCY_KEY=$(openssl rand -hex 16)    # keep it until you have the answer

# 1. A new key and a signing request, on the client's machine
rm -f client_key.pem                       # permissions only apply to new files
openssl req -new -newkey ec -pkeyopt ec_paramgen_curve:P-256 -nodes \
  -keyout client_key.pem -out client.csr -subj "/CN=new client"

# 2. Create the client. --retry repeats the same request after a timeout or a
#    temporary error such as 503, with the same Idempotency-Key and body.
RESPONSE=$(curl -s --retry 4 -X POST https://api.knovas.ch/onboard_client \
  -H "Authorization: Knovas-Org-Key $KNOVAS_ORG_KEY" \
  -H "Idempotency-Key: $IDEMPOTENCY_KEY" \
  -H "Content-Type: application/json" \
  -d "$(jq -n --rawfile csr client.csr \
        '{first_name: "Jane", last_name: "Doe", email: "jane.doe@example.ch", csr_pem: $csr}')")

echo "$RESPONSE" | jq -r '.client_id'
echo "$RESPONSE" | jq -r '.certificate_pem' > client_cert.pem
echo "$RESPONSE" | jq -r '.ca_root_cert'    > ca_root_cert.pem

The client can use its new certificate on port 8443 straight away (see Test the connection). Keep client_id: renewing needs it. Without csr_pem the answer also has private_key: save it at once, readable by you only, because Knovas never sends it again.

Answers

An error answer looks like {"status": "error", "error": "…", "error_code": "…"}; a 400 also names the field where it can.

AnswerWhat it meansWhat to do
201Client created. The answer has client_id, certificate_serial, certificate_pem, ca_root_cert, clients_left and, without csr_pem, private_key.Save the files.
200You sent the same request again (same Idempotency-Key, same body): the first answer, without a private key.Use it like the first answer.
400 VALIDATION_ERROR, UNKNOWN_FIELD, FORBIDDEN_FIELD, INVALID_EMAIL, INVALID_CSRA field, the Idempotency-Key or the signing request is not valid.Fix the request.
401 UNAUTHENTICATEDThe key is missing, wrong, revoked or expired, or your organisation is not active. The answer is the same for every cause.Check the key. If it is right, ask Knovas.
403 ONBOARDING_KEY_EXHAUSTEDThe key has created all the clients it may.Ask Knovas to raise the limit or issue a new key.
403 ONBOARDING_KEY_NO_CONTACTNobody can receive the notices for this key.Ask Knovas to name a contact.
404 FEATURE_DISABLEDCreating clients is not switched on where you sent the request.Ask Knovas.
409 DUPLICATE_CLIENTA client of your organisation already has this email address. The answer does not say which.For a second client, send "allow_duplicate": true.
422 IDEMPOTENCY_KEY_REUSEDThis Idempotency-Key was used before for a different request.Use a new Idempotency-Key for a new client.
429 ONBOARDING_RATE_LIMITEDThe key had 20 events in the last hour. When the hour is full, a duplicate gets this answer too, not 409.Wait and retry.
429 without a codeMore than 30 requests a minute from your address (short bursts of 10).Wait and retry.
500 CLIENT_CREATION_FAILEDNothing was saved.Retry.
503 CLIENT_CREATION_UNCERTAINKnovas does not know whether the client was saved.Retry with the same Idempotency-Key and body: you get the stored answer (200) or a new attempt (201).
503 SERVICE_UNAVAILABLEThe certificate service is not available.Retry later.

Retrying safely

Send a new Idempotency-Key for every new client: 1 to 100 characters from A–Z a–z 0–9 . _ : - (a UUID fits). Keep it, with the exact body, until you have the answer. A retry with the same key and the same body gets the stored answer (200). It creates no second client, does not count against the key’s limits, and works even if the key has reached a limit meanwhile, as long as the key itself is still valid. Change anything in the body (a new signing request, another field order) and it is a different request (422).

If the answer is lostWhat it costs
With csr_pem and an Idempotency-KeyNothing. Retry and you get the certificate.
Without csr_pemThe private key was only in the lost answer and is never sent again, so that client cannot be used. Create a new one with "allow_duplicate": true and a new Idempotency-Key, and tell Knovas the unusable client’s id.
Without an Idempotency-KeyA retry is a new request. If the first one was saved, the retry gets 409 DUPLICATE_CLIENT.

So: send a signing request, and always send an Idempotency-Key.

Renewing a client’s certificate

A client whose certificate still works renews it itself on port 8443 (see Create your own key); no organisation key is needed. Use the organisation key when your organisation renews centrally, or when the certificate has already expired: port 8443 refuses an expired certificate, but it can still prove possession here.

Renewing needs both your organisation key and a proof of possession: a signature over a short message, made with the private key of the client’s current certificate. Either alone renews nothing. A client whose private key is lost, or whose certificate is an older one without OU=Semantix-Customer-<client id> (or was signed by an earlier Knovas client CA), cannot renew this way: ask Knovas to issue a new certificate.

Call (port 443)Who makes the new keyBody
POST /sign_certificateYou (signing request)customer_id, csr, validity_days, current_certificate, possession_proof
POST /generate_certificateKnovascertificate_data (only customer_id and validity_days), current_certificate, possession_proof
  • customer_id: the client’s client_id, written with hyphens (8-4-4-4-12).
  • validity_days: 1 to 365 (default 365).
  • current_certificate: the client’s current certificate, exactly one PEM block (no chain, no key). It may be expired. Its key must be RSA with at least 2048 bits, or EC on P-256 or P-384.
  • possession_proof: {"signed_at": …, "signature": …}, built as below. Build a new one for every attempt.

The proof of possession

The message has five lines of text, each ending in a line break (\n), the last one too:

Message
knovas-renew-v1
<client id, lower-case, with hyphens>
<serial number of current_certificate, in decimal>
<SHA-256 of the new public key, or server-generated>
<signed_at: the time now, in Unix seconds>
  • Line 4 for /sign_certificate: the SHA-256 of the new public key’s SubjectPublicKeyInfo (DER), as 64 lower-case hex digits. For /generate_certificate: the word server-generated.
  • signed_at must be within 5 minutes of Knovas’ clock. In the body it is a number, not a string.
  • Sign the message with the client’s current private key. An RSA key signs with RSASSA-PSS (SHA-256, MGF1 with SHA-256, salt length 32); keys Knovas made are RSA. An EC key signs with ECDSA and SHA-256.
  • signature is the signature in standard base64 (with = padding) on one line, with no spaces or line breaks.

The example renews with a signing request. It reads the client’s current files client_cert.pem and client_key.pem and writes new_client_key.pem and new_client_cert.pem:

umask 077
CLIENT_ID=$(printf '%s' "<client id>" | tr 'A-F' 'a-f')   # client_id from /onboard_client

# 1. A new key and a signing request. Keep the new key even if the call fails.
rm -f new_client_key.pem
openssl req -new -newkey ec -pkeyopt ec_paramgen_curve:P-256 -nodes \
  -keyout new_client_key.pem -out new_client.csr -subj "/CN=renewal"

# 2. The message: five lines, each ending in \n
SERIAL=$(openssl x509 -in client_cert.pem -noout -serial | cut -d= -f2)
SERIAL=$(echo "ibase=16; $SERIAL" | BC_LINE_LENGTH=0 bc)     # hex to decimal
NEW_KEY=$(openssl req -in new_client.csr -noout -pubkey | openssl pkey -pubin -outform DER \
  | openssl dgst -sha256 -r | cut -d' ' -f1)
SIGNED_AT=$(date +%s)
printf 'knovas-renew-v1\n%s\n%s\n%s\n%s\n' "$CLIENT_ID" "$SERIAL" "$NEW_KEY" "$SIGNED_AT" > renewal.txt

# 3. Sign it with the CURRENT private key. An RSA key (all keys made by Knovas):
SIGNATURE=$(openssl dgst -sha256 -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:32 \
  -sigopt rsa_mgf1_md:sha256 -sign client_key.pem renewal.txt | openssl base64 -A)
# An EC key instead:
# SIGNATURE=$(openssl dgst -sha256 -sign client_key.pem renewal.txt | openssl base64 -A)

# 4. Renew. On an error the answer has an error_code instead (see below).
RESPONSE=$(curl -s -X POST https://api.knovas.ch/sign_certificate \
  -H "Authorization: Knovas-Org-Key $KNOVAS_ORG_KEY" \
  -H "Content-Type: application/json" \
  -d "$(jq -n --arg id "$CLIENT_ID" --rawfile csr new_client.csr --rawfile cert client_cert.pem \
        --argjson at "$SIGNED_AT" --arg sig "$SIGNATURE" \
        '{customer_id: $id, csr: $csr, validity_days: 365, current_certificate: $cert,
          possession_proof: {signed_at: $at, signature: $sig}}')")
echo "$RESPONSE" | jq -r '.certificate' > new_client_cert.pem

For /generate_certificate, line 4 is server-generated, the body is {"certificate_data": {"customer_id": …, "validity_days": …}, "current_certificate": …, "possession_proof": …}, and the answer carries the new private_key (encrypted) with its private_key_password. A complete program with error handling is in the Organisation Onboarding reference of the Knovas Developer Kit; your Knovas contact sends it with the key.

After a renewal

  • The old certificate keeps working for 48 hours, then Knovas refuses it. Switch the client to the new certificate and key within those 48 hours.
  • The old certificate cannot prove a second renewal. Next time, prove with the new one.
  • Every renewal sends a notice to your contact and counts against the key’s 20 events an hour. It does not use up a client from the key’s limit.
  • If the answer is lost, the proof is used up and the new certificate is not sent again. If the old certificate had not expired, it still works for 48 hours: use it to renew on port 8443. If it had expired, contact Knovas.
AnswerWhat it means
200Renewed. /sign_certificate: certificate, certificate_chain, serial_number, expires_at. /generate_certificate: certificate_pem, private_key, private_key_password, ca_root_cert.
400 VALIDATION_ERROR, UNKNOWN_FIELD, INVALID_CSRThe body is not valid, for example validity_days outside 1–365.
401 UNAUTHENTICATEDThe organisation key failed.
403 POSSESSION_PROOF_INVALIDThe proof does not hold: wrong signature or message, signed_at more than 5 minutes off, a certificate Knovas did not issue to this client, a revoked one, or one that already proved a renewal. The answer does not say which.
403 ONBOARDING_KEY_NO_CONTACTNobody can receive the notices for this key. Ask Knovas.
404 NOT_FOUNDThe client does not exist or is not in your organisation (the same answer for both).
409 POSSESSION_PROOF_REUSEDThis exact proof was used already. Build a new one.
429ONBOARDING_RATE_LIMITED: 20 events in the last hour for this key. Without a code: more than 30 requests a minute from your address.
500 RENEWAL_FAILEDNothing was saved. Retry with a new proof.
503 RENEWAL_UNCERTAINKnovas does not know whether the renewal was saved. See below.
503 SERVICE_UNAVAILABLENothing was issued. Retry later with a new proof.
If the outcome is unknown

After 503 RENEWAL_UNCERTAIN, a gateway error (502, 504) or any answer your software does not know:

  • Keep the new private key and the current certificate and key. A certificate may already exist for the new key.
  • Do not retry with a new proof. If the renewal was saved, the current certificate has already proved once, and every further try is refused.
  • If the current certificate has not expired, renew on port 8443 (see Create your own key).
  • If it has expired, contact Knovas with the client id and the time of the request.

Questions? Write to contact@knovas.ch.

This page describes Knovas 1.6.0. Last updated .