Update RTD with certificate update use case
[oom/platform/cert-service.git] / docs / sections / usage.rst
index 4857099..cd48b55 100644 (file)
 .. This work is licensed under a Creative Commons Attribution 4.0 International License.
 .. http://creativecommons.org/licenses/by/4.0
-.. Copyright 2020 NOKIA
+.. Copyright 2020-2021 NOKIA
+
+.. _cmpv2_cert_provider:
 
 How to use functionality
 =========================
-Common information to docker and Kubernetes modes described below
-
-Basic information
------------------
-CertService client needs the following configuration parameters to work properly:
-
-1. Parameters for generating certification artifacts and connecting to CertService API to obtain certificate and trust anchors
-  
-  - REQUEST_URL *(default: https://oom-cert-service:8443/v1/certificate/)* - URL to CertService API
-  - REQUEST_TIMEOUT *(default: 30000[ms])* - Timeout in milliseconds for REST API calls
-  - OUTPUT_PATH *(required)* - Path where client will output generated certificate and trust anchor
-  - CA_NAME *(required)* - Name of CA which will enroll certificate. Must be same as configured on server side. Used in REST API calls
-  - OUTPUT_TYPE *(default: P12)* - Type of certificate which will be generated. Supported types: 
-      
-      - JKS - Java KeyStore (JKS)
-      - P12 - Public Key Cryptography Standard #12 (PKCS#12)
-      - PEM - Privacy-Enhanced Mail (PEM)
-
-
-2. Parameters to generate Certificate Signing Request (CSR):
-  
-  - COMMON_NAME *(required)* - Common name for which certificate from CMPv2 server should be issued
-  - ORGANIZATION *(required)* - Organization for which certificate from CMPv2 server should be issued
-  - ORGANIZATION_UNIT *(optional)* - Organization unit for which certificate from CMPv2 server should be issued
-  - LOCATION *(optional)* - Location for which certificate from CMPv2 server should be issued
-  - STATE *(required)* - State for which certificate from CMPv2 server should be issued
-  - COUNTRY *(required)* - Country for which certificate from CMPv2 server should be issued
-  - SANS *(optional)(SANS's should be separated by a comma e.g. test.onap.org,onap.com)* - Subject Alternative Names (SANs) for which certificate from CMPv2 server should be issued.
-
-3. Parameters to establish secure communication to CertService:
-
-  - KEYSTORE_PATH *(required)*
-  - KEYSTORE_PASSWORD *(required)*
-  - TRUSTSTORE_PATH *(required)*
-  - TRUSTSTORE_PASSWORD *(required)*
+Common information how to use CMPv2 certificate provider described below
 
-CertService client image can be found on Nexus repository :
-
-.. code-block:: bash
-
-  nexus3.onap.org:10001/onap/org.onap.oom.platform.cert-service.oom-certservice-client:$VERSION
-
-
-As standalone docker container
+General information
 ------------------------------
-You need certificate and trust anchors to connect to CertService API via HTTPS. Information how to generate truststore and keystore files you can find in project repository README `Gerrit GitWeb <https://gerrit.onap.org/r/gitweb?p=oom%2Fplatform%2Fcert-service.git;a=summary>`__
 
-To run CertService client as standalone docker container execute following steps:
+CMPv2 certificate provider is a part of certificate distribution infrastructure in ONAP.
+The main functionality of the provider is to forward Certificate Signing Requests (CSRs) created by cert-mananger (https://cert-manager.io) to CertServiceAPI.
 
-1. Create file '*$PWD/client.env*' with environment variables as in example below:
+Additional information can be found on a dedicated page:  https://wiki.onap.org/display/DW/CertService+and+K8s+Cert-Manager+integration.
 
-.. code-block:: bash
+By default CMPv2 provider is enabled.
 
-  #Client envs
-  REQUEST_URL=<URL to CertService API>
-  REQUEST_TIMEOUT=10000
-  OUTPUT_PATH=/var/certs
-  CA_NAME=RA
-  OUTPUT_TYPE=P12
+CMPv2 Issuer
+------------------------------
 
-  #CSR config envs
-  COMMON_NAME=onap.org
-  ORGANIZATION=Linux-Foundation
-  ORGANIZATION_UNIT=ONAP
-  LOCATION=San-Francisco
-  STATE=California
-  COUNTRY=US
-  SANS=test.onap.org,onap.com
+In order to be able to request a certificate via CMPv2 provider a *CMPv2Issuer* CRD (Customer Resource Definition) instance has to be created.
 
-  #TLS config envs
-  KEYSTORE_PATH=/etc/onap/oom/certservice/certs/certServiceClient-keystore.jks
-  KEYSTORE_PASSWORD=<password to certServiceClient-keystore.jks>
-  TRUSTSTORE_PATH=/etc/onap/oom/certservice/certs/certServiceClient-truststore.jks
-  TRUSTSTORE_PASSWORD=<password to certServiceClient-truststore.jks>
+It is important to note that the attribute *kind* has to be set to **CMPv2Issuer**, all other attributes can be set as needed.
 
-2. Run docker container as in following example (API and client must be running in same network):
+**NOTE: a default instance of CMPv2Issuer is created when installing ONAP via OOM deployment.**
 
-.. code-block:: bash
+Here is a definition of a *CMPv2Issuer* provided with ONAP installation:
 
- docker run \
-    --rm \
-    --name oomcert-client \
-    --env-file <$PWD/client.env (same as in step1)> \
-    --network <docker network of cert service> \
-    --mount type=bind,src=<path to local host directory where certificate and trust anchor will be created>,dst=<OUTPUT_PATH (same as in step 1)> \
-    --volume <local path to keystore in JKS format>:<KEYSTORE_PATH> \
-    --volume <local path to truststore in JKS format>:<TRUSTSTORE_PATH> \
-    nexus3.onap.org:10001/onap/org.onap.oom.platform.cert-service.oom-certservice-client:$VERSION
+.. code-block:: yaml
 
+  apiVersion: certmanager.onap.org/v1
+  kind: CMPv2Issuer
+  metadata:
+    name: cmpv2-issuer-onap
+    namespace: onap
+  spec:
+    url: https://oom-cert-service:8443
+    healthEndpoint: actuator/health
+    certEndpoint: v1/certificate
+    updateEndpoint: v1/certificate-update
+    caName: RA
+    certSecretRef:
+      name: cmpv2-issuer-secret
+      certRef: cmpv2Issuer-cert.pem
+      keyRef: cmpv2Issuer-key.pem
+      cacertRef: cacert.pem
+
+
+Certificate enrolling
+------------------------------
 
+In order to request a certificate a K8s *Certificate* CRD (Custom Resource Definition) has to be created.
 
-After successful creation of certifications, container exits with exit code 0, expected log looks like:
+It is important that in the section issuerRef following attributes have those values:
 
-.. code-block:: bash
+- group: certmanager.onap.org
 
-   INFO 1 [           main] o.o.a.c.c.c.f.ClientConfigurationFactory : Successful validation of Client configuration. Configuration data: REQUEST_URL: https://oom-cert-service:8443/v1/certificate/, REQUEST_TIMEOUT: 10000, OUTPUT_PATH: /var/certs, CA_NAME: RA, OUTPUT_TYPE: P12
-   INFO 1 [           main] o.o.a.c.c.c.f.CsrConfigurationFactory    : Successful validation of CSR configuration. Configuration data: COMMON_NAME: onap.org, COUNTRY: US, STATE: California, ORGANIZATION: Linux-Foundation, ORGANIZATION_UNIT: ONAP, LOCATION: San-Francisco, SANS: test.onap.org:onap.org
-   INFO 1 [           main] o.o.a.c.c.c.KeyPairFactory               : KeyPair generation started with algorithm: RSA and key size: 2048
-   INFO 1 [           main] o.o.a.c.c.c.CsrFactory                   : Creation of CSR has been started with following parameters: COMMON_NAME: onap.org, COUNTRY: US, STATE: California, ORGANIZATION: Linux-Foundation, ORGANIZATION_UNIT: ONAP, LOCATION: San-Francisco, SANS: test.onap.org:onap.org
-   INFO 1 [           main] o.o.a.c.c.c.CsrFactory                   : Creation of CSR has been completed successfully
-   INFO 1 [           main] o.o.a.c.c.c.CsrFactory                   : Conversion of CSR to PEM has been started
-   INFO 1 [           main] o.o.a.c.c.c.PrivateKeyToPemEncoder       : Attempt to encode private key to PEM
-   INFO 1 [           main] o.o.a.c.c.h.HttpClient                   : Attempt to send request to API, on url: https://oom-cert-service:8443/v1/certificate/RA
-   INFO 1 [           main] o.o.a.c.c.h.HttpClient                   : Received response from API
-  DEBUG 1 [           main] o.o.a.c.c.c.c.ConvertedArtifactsCreator  : Attempt to create keystore files and saving data. File names: keystore.p12, keystore.pass
-   INFO 1 [           main] o.o.a.c.c.c.c.PemConverter               : Conversion of PEM certificates to PKCS12 keystore
-  DEBUG 1 [           main] o.o.a.c.c.c.w.CertFileWriter             : Attempt to save file keystore.p12 in path /var/certs
-  DEBUG 1 [           main] o.o.a.c.c.c.w.CertFileWriter             : Attempt to save file keystore.pass in path /var/certs
-  DEBUG 1 [           main] o.o.a.c.c.c.c.ConvertedArtifactsCreator  : Attempt to create truststore files and saving data. File names: truststore.p12, truststore.pass
-   INFO 1 [           main] o.o.a.c.c.c.c.PemConverter               : Conversion of PEM certificates to PKCS12 truststore
-  DEBUG 1 [           main] o.o.a.c.c.c.w.CertFileWriter             : Attempt to save file truststore.p12 in path /var/certs
-  DEBUG 1 [           main] o.o.a.c.c.c.w.CertFileWriter             : Attempt to save file truststore.pass in path /var/certs
-   INFO 1 [           main] o.o.a.c.c.AppExitHandler                 : Application exits with following exit code: 0 and message: Success
+- kind: CMPv2Issuer
 
+After *Certificate* CRD has been placed cert manager will send a *CSR* (Certificate Sign Request) to CA (Certificate Authority) via CMPv2 provider.
+Signed certificate as well as trust anchor (CA root certificate) will be stored in the K8s *secret* specified in *Certificate* CRD (see secretName attribute).
 
+By default certificates will be stored in PEM format. It is possible to get certificates also in JKS and P12 format - see example below - more information can be found on official cert manager page.
 
+The following SANs types are supported: DNS names, IPs, URIs, emails.
 
-If container exits with non 0 exit code, you can find more information in logs, see :ref:`cert_logs` page.
+Here is an example of a *Certificate*:
 
-As init container for Kubernetes
---------------------------------
+.. code-block:: yaml
 
-In order to run CertService client as init container for ONAP component you need to:
+  apiVersion: cert-manager.io/v1
+  kind: Certificate
+  metadata:
+    name: certificate_name
+    namespace: onap
+  spec:
+    # The secret name to store the signed certificate
+    secretName: secret_name
+    # Common Name
+    commonName: certissuer.onap.org
+    subject:
+      organizations:
+        - Linux-Foundation
+      countries:
+        - US
+      localities:
+        - San-Francisco
+      provinces:
+        - California
+      organizationalUnits:
+        - ONAP
+    # SANs
+    dnsNames:
+      - localhost
+      - certissuer.onap.org
+    ipAddresses:
+      - "127.0.0.1"
+    uris:
+      - onap://cluster.local/
+    emailAddresses:
+      - onap@onap.org
+    # The reference to the CMPv2 issuer
+    issuerRef:
+      group: certmanager.onap.org
+      kind: CMPv2Issuer
+      name: cmpv2-issuer-onap
+    # Section keystores is optional and defines in which format certificates will be stored
+    # If this section is omitted than only PEM format will be present in the secret
+    keystores:
+        jks:
+          create: true
+          passwordSecretRef: # Password used to encrypt the keystore
+            name: certservice-key
+            key: key
+        pkcs12:
+          create: true
+          passwordSecretRef: # Password used to encrypt the keystore
+            name: certservice-key
+            key: key
+
+
+Here is an example of generated *secret* containing certificates:
 
-    - define an init container and use CerService Client image
-    - provide client configuration through ENV variables in the init container
-    - define two volumes:
+.. code-block:: yaml
 
-        - first for generated certificates - it will be mounted in the init container and in the component container
-        - second with secret containing keys and certificates for secure communication between CertService Client and CertService - it will be mounted only in the init container
-    - mount both volumes to the init container
-    - mount first volume to the component container
+    Name:         secret_name
+    Namespace:    onap
+    Labels:       <none>
+    Annotations:  cert-manager.io/alt-names: localhost,certissuer.onap.org
+                  cert-manager.io/certificate-name: certificate_name
+                  cert-manager.io/common-name: certissuer.onap.org
+                  cert-manager.io/ip-sans:
+                  cert-manager.io/issuer-group: certmanager.onap.org
+                  cert-manager.io/issuer-kind: CMPv2Issuer
+                  cert-manager.io/issuer-name: cmpv2-issuer-onap
+                  cert-manager.io/uri-sans:
+
+    Type:  kubernetes.io/tls
+
+    Data
+    ====
+    tls.crt:         1675 bytes  <-- Certificate (PEM)
+    tls.key:         1679 bytes  <-- Private Key (PEM)
+    truststore.jks:  1265 bytes  <-- Trusted anchors (JKS)
+    ca.crt:          1692 bytes  <-- Trusted anchors (PEM)
+    keystore.jks:    3786 bytes  <-- Certificate and Private Key (JKS)
+    keystore.p12:    4047 bytes  <-- Certificate and Private Key (P12)
+
+.. _how_to_use_certificate_update:
+
+Certificate update
+------------------------------
 
-You can use the following deployment example as a reference:
+When the certificate already exists, but its date has expired or certificate data should be changed, then the certificate update scenario can be executed.
+This use case requires the update endpoint configured for *CMPv2Issuer* CRD:
 
 .. code-block:: yaml
 
-    ...
-  kind: Deployment
-  metadata:
-    ...
-  spec:
   ...
-    template:
-    ...
-      spec:
-        containers:
-          - image: sample.image
-            name: sample.name 
-            ...
-            volumeMounts:
-              - mountPath: /var/certs #CERTS CAN BE FOUND IN THIS DIRECTORY
-                name: certs
-            ...
-        initContainers:
-          - name: cert-service-client
-            image: nexus3.onap.org:10001/onap/org.onap.oom.platform.cert-service.oom-certservice-client:latest
-            imagePullPolicy: Always
-            env:
-              - name: REQUEST_URL
-                value: https://oom-cert-service:8443/v1/certificate/
-              - name: REQUEST_TIMEOUT
-                value: "1000"
-              - name: OUTPUT_PATH
-                value: /var/certs
-              - name: CA_NAME
-                value: RA
-              - name: OUTPUT_TYPE
-                value: P12
-              - name: COMMON_NAME
-                value: onap.org
-              - name: ORGANIZATION
-                value: Linux-Foundation
-              - name: ORGANIZATION_UNIT
-                value: ONAP
-              - name: LOCATION
-                value: San-Francisco
-              - name: STATE
-                value: California
-              - name: COUNTRY
-                value: US
-              - name: SANS
-                value: test.onap.org:onap.com
-              - name: KEYSTORE_PATH
-                value: /etc/onap/oom/certservice/certs/certServiceClient-keystore.jks
-              - name: KEYSTORE_PASSWORD
-                value: secret
-              - name: TRUSTSTORE_PATH
-                value: /etc/onap/oom/certservice/certs/truststore.jks
-              - name: TRUSTSTORE_PASSWORD
-                value: secret
-            volumeMounts:
-              - mountPath: /var/certs
-                name: certs
-              - mountPath: /etc/onap/oom/certservice/certs/
-                name: tls-volume
-          ...
-        volumes: 
-        - name: certs
-          emptyDir: {}
-        - name tls-volume
-          secret:
-            secretName: oom-cert-service-client-tls-secret  # Value of global.oom.certService.client.secret.name
-        ...
+  certEndpoint: v1/certificate
+  updateEndpoint: v1/certificate-update
+  caName: RA
+  ...
+
+If *updateEndpoint* field is not present or empty, then *certEndpoint* will be used (regular initial request instead of update) to get the certificate and this event will be logged.
+This behavior comes from releases prior to 2.4.0, when the certificate update feature was not implemented. To be able to perform the certificate update scenario,
+make sure the updateEndpoint is present in *CMPv2Issuer* CRD.
+
+There are two possible types of requests when a certificate needs to be updated: Key Update Request (KUR) and Certification Request (CR).
+Certification Service internally compares the old and new certificates fields. When they are equal, KUR request is sent.
+If there is a difference, the type of request is CR.
 
+There is a difference between CR and KUR in terms of the request authentication. Certificate Request uses IAK/RV mechanism, while KUR uses signature protection.
+The old certificate and the old private key are required to be sent in the headers of the update request.