# yaml-language-server: $schema=../../../../api/jsonschema/harp.bundle.v1/Template.json
apiVersion: harp.elastic.co/v1
kind: BundleTemplate

meta:
  name: "Ecebootstrap"
  owner: syseng@elstc.co
  description: "ECE Secret Bootstrap"

spec:
  selector:
    quality: "{{ .Values.quality }}"
    platform: "{{ .Values.platform.essp.name }}"
    product: "ece"
    version: "{{ .Values.product.version }}"

  namespaces:

    #
    # Infrastructure secret templates
    #
    # Generates all secrets that will be pulled by TF to provision resources.
    #
    infrastructure:
    # AWS ----------------------------------------------------------------------
    - provider: "aws"
      account: "{{ .Values.infra.aws.account }}"
      description: "ESSP AWS Account"
      regions:
      - name: "us-east-1"
        services:
        - type: "rds"
          name: "adminconsole"
          description: "PostgreSQL Database used for AdminConsole storage backend"
          secrets:
          - suffix: "accounts/root_credentials"
            description: "Root Admin Account"
            labels:
                database: "postgresql"
                admin: "true"
            annotations:
                infosec.elastic.co/v1/SecretPolicy#severity: critical
                infosec.elastic.co/v1/SecretPolicy#rotationPeriod: "180"
                infosec.elastic.co/v1/SecretPolicy#generationDate: "{{ now | isodate }}"
            template: |-
              {
                "user": "dbroot-{{ randAlphaNum 8 }}",
                "password": "{{ paranoidPassword | b64enc }}"
              }

    #
    # Platform secret templates
    #
    # Software / Services deployed on Cloud Provider Resources as a logical
    # infrastructure for Products and Applications.
    #
    platform:
      # US-EAST-1
      - region: "us-east-1"
        components:
        # Zookeeper --------------------------------------------------------------
        - name: "zookeeper"
          secrets:
          - suffix: "accounts/admin_credentials"
            description: "Zookeeper administrative access account"
            labels:
                admin: "true"
            annotations:
                infosec.elastic.co/v1/SecretPolicy#serviceType: kvstore
                infosec.elastic.co/v1/SecretPolicy#serviceVendor: zookeeper
                infosec.elastic.co/v1/SecretPolicy#severity: critical
                infosec.elastic.co/v1/SecretPolicy#rotationPeriod: "180"
                infosec.elastic.co/v1/SecretPolicy#generationDate: "{{ now | isodate }}"
            template: |-
              {
                "username": "zkadmin-{{ randAlphaNum 8 }}",
                "password": "{{ paranoidPassword | b64enc}}"
              }

        # PostgreSQL -------------------------------------------------------------
        - name: "postgresql"
          secrets:
          - suffix: "admiconsole/admin_credentials"
            description: "PostgreSQL Administrative access on Database only"
            labels:
                database: "postgresql"
                admin: "true"
            annotations:
                infosec.elastic.co/v1/SecretPolicy#serviceType: database
                infosec.elastic.co/v1/SecretPolicy#serviceVendor: postgresql
                infosec.elastic.co/v1/SecretPolicy#severity: critical
                infosec.elastic.co/v1/SecretPolicy#rotationPeriod: "180"
                infosec.elastic.co/v1/SecretPolicy#generationDate: "{{ now | isodate }}"
            template: |-
              {
                "username": "dbadmin-{{ randAlphaNum 8 }}",
                "password": "{{ paranoidPassword | b64enc }}"
              }

        # Billing ----------------------------------------------------------------
        - name: "billing"
          secrets:
          - suffix: "recurly/vendor_api_key"
            description: "Recurly API Key for invoice generation"
            labels:
                api_key: "true"
            annotations:
                infosec.elastic.co/v1/SecretPolicy#serviceType: billing
                infosec.elastic.co/v1/SecretPolicy#serviceVendor: recurly
                infosec.elastic.co/v1/SecretPolicy#severity: moderate
                infosec.elastic.co/v1/SecretPolicy#rotationPeriod: "60"
                infosec.elastic.co/v1/SecretPolicy#generationDate: "{{ now | isodate }}"
                infosec.elastic.co/v1/SecretPolicy#rotationMethod: manual
            # Not generated by workflow, requested at generation time.
            vendor: true
            template: |-
              {
                "API_KEY": "{{ .Values.vendor.recurly.api_key }}"
              }
            content:
              "ca.pem": |-
                -----BEGIN CERTIFICATE-----
                MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw
                TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
                cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4
                WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu
                ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY
                MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc
                h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+
                0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U
                A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW
                T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH
                B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC
                B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv
                KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn
                OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn
                jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw
                qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI
                rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
                HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq
                hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL
                ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ
                3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK
                NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5
                ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur
                TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC
                jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc
                oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq
                4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA
                mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d
                emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=
                -----END CERTIFICATE-----


    #
    # Product secret templates
    #
    # Secret generated and consumed by application components not bound to
    # running environment.
    #
    product:
    - name: artifact
      description: "Artifact"
      secrets:

      - suffix: "signature/key"
        description: "Artifact signature crypto key"
        labels:
            cicd: "true"
        annotations:
            infosec.elastic.co/v1/SecretPolicy#serviceType: supplychain
            infosec.elastic.co/v1/SecretPolicy#severity: critical
            infosec.elastic.co/v1/SecretPolicy#rotationPeriod: "720"
            infosec.elastic.co/v1/SecretPolicy#generationDate: "{{ now | isodate }}"
        template: |-
          {
            "privateKey": "{{ $sigKey := cryptoPair "rsa" }}{{ $sigKey.Private | toJwk | b64enc }}",
            "publicKey": "{{ $sigKey.Public | toJwk | b64enc }}"
          }

    #
    # Application secret templates
    #
    # Secrets generated and consumed by application components depending on the
    # application running environment quality level (dev, qa, staging, production),
    # passed as an argument during genesis.
    #
    application:

    # AdminConsole -------------------------------------------------------------
    - name: "adminconsole"
      description: "Administration UI console"
      secrets:

      - suffix: "authentication/otp/okta_api_key"
        description: "Okta API Key for OTP validation"
        labels:
            okta: "true"
        annotations:
            infosec.elastic.co/v1/SecretPolicy#serviceType: authentication
            infosec.elastic.co/v1/SecretPolicy#severity: okta
            infosec.elastic.co/v1/SecretPolicy#rotationPeriod: "180"
            infosec.elastic.co/v1/SecretPolicy#generationDate: "{{ now | isodate }}"
            infosec.elastic.co/v1/SecretPolicy#rotationMethod: rundeck
            infra.elastic.co/v1/Rundeck#jobName: rotate-adminconsole-okta-api-key
        # Not generated by workflow, requested at generation time.
        vendor: true
        template: |-
          {
            "API_KEY": "{{ .Values.vendor.okta.api_key }}"
          }

      - suffix: "database/usage_credentials"
        description: "PostgreSQL database account for component usage"
        labels:
            database: "postgresql"
        annotations:
            infosec.elastic.co/v1/SecretPolicy#serviceType: database
            infosec.elastic.co/v1/SecretPolicy#serviceVendor: postgresql
            infosec.elastic.co/v1/SecretPolicy#severity: moderate
            infosec.elastic.co/v1/SecretPolicy#generationDate: "{{ now | isodate }}"
            infosec.elastic.co/v1/SecretPolicy#rotationPeriod: on-new-version
        template: |-
          {
            "host": "sample-instance.abc2defghije.us-west-2.rds.amazonaws.com",
            "port": "5432",
            "options": "sslmode=require&application_name={{ .Data.Component }}",
            "username": "dbuser-{{ .Data.Component }}-{{ randAlphaNum 8 }}",
            "password": "{{ paranoidPassword | b64enc }}",
            "dbname": "{{ .Data.Component }}"
          }

      - suffix: "mailing/sender/mailgun_api_key"
        description: "Mailgun API Key for sending email"
        annotations:
            infosec.elastic.co/v1/SecretPolicy#serviceType: mailing
            infosec.elastic.co/v1/SecretPolicy#serviceVendor: mailgun
            infosec.elastic.co/v1/SecretPolicy#severity: moderate
            infosec.elastic.co/v1/SecretPolicy#generationDate: "{{ now | isodate }}"
            infosec.elastic.co/v1/SecretPolicy#rotationPeriod: on-new-version
        # Not generated by workflow, requested at generation time.
        vendor: true
        template: |-
          {
            "API_KEY": "{{ .Values.vendor.mailgun.api_key }}"
          }

      - suffix: "http/session"
        description: "HTTP Session settings"
        annotations:
            infosec.elastic.co/v1/SecretPolicy#serviceType: http
            infosec.elastic.co/v1/SecretPolicy#severity: moderate
            infosec.elastic.co/v1/SecretPolicy#generationDate: "{{ now | isodate }}"
            infosec.elastic.co/v1/SecretPolicy#rotationPeriod: on-new-version
        template: |-
          {
            "cookieEncryptionKey": "{{ customPassword 128 20 10 false true | b64enc }}",
            "sessionSaltSeed": "{{ customPassword 128 20 10 false true | b64enc }}",
            "jwtHmacKey": "{{ paranoidPassword | b64enc }}"
          }

      - suffix: "privacy/anonymizer"
        description: "Anonymizer settings"
        annotations:
            infosec.elastic.co/v1/SecretPolicy#serviceType: data
            infosec.elastic.co/v1/SecretPolicy#severity: moderate
            infosec.elastic.co/v1/SecretPolicy#generationDate: "{{ now | isodate }}"
            infosec.elastic.co/v1/SecretPolicy#rotationPeriod: never
        template: |-
          {
            "emailHashPepperSeedKey": "{{ customPassword 128 20 10 false true | b64enc }}"
          }

    # UserConsole --------------------------------------------------------------
    - name: "userconsole"
      description: "Customer facing UI console"
      secrets:

      - suffix: "database/usage_credentials"
        description: "PostgreSQL database account for component usage"
        labels:
            database: "postgresql"
        annotations:
            infosec.elastic.co/v1/SecretPolicy#serviceType: database
            infosec.elastic.co/v1/SecretPolicy#serviceVendor: postgresql
            infosec.elastic.co/v1/SecretPolicy#severity: moderate
            infosec.elastic.co/v1/SecretPolicy#generationDate: "{{ now | isodate }}"
            infosec.elastic.co/v1/SecretPolicy#rotationPeriod: on-new-version
        template: |-
          {
            "host": "sample-instance.abc2defghije.us-west-2.rds.amazonaws.com",
            "port": "5432",
            "options": "sslmode=require&application_name={{.Data.Component}}",
            "username": "dbuser-{{.Data.Component}}-{{ randAlphaNum 8 }}",
            "password": "{{ paranoidPassword | b64enc }}",
            "dbname": "{{ .Data.Component }}"
          }

      - suffix: "http/session"
        description: "HTTP Session settings"
        annotations:
            infosec.elastic.co/v1/SecretPolicy#serviceType: http
            infosec.elastic.co/v1/SecretPolicy#severity: moderate
            infosec.elastic.co/v1/SecretPolicy#rotationPeriod: "7"
            infosec.elastic.co/v1/SecretPolicy#generationDate: "{{ now | isodate }}"
        template: |-
          {
            "cookieEncryptionKey": "{{ customPassword 128 20 10 false true | b64enc }}",
            "sessionSaltSeed": "{{ customPassword 128 20 10 false true | b64enc }}",
            "jwtHmacKey": "{{ paranoidPassword | b64enc }}"
          }

      - suffix: "http/certificate"
        description: "HTTPS settings"
        annotations:
            infosec.elastic.co/v1/SecretPolicy#serviceType: http
            infosec.elastic.co/v1/SecretPolicy#severity: critical
            infosec.elastic.co/v1/SecretPolicy#rotationPeriod: "90"
            infosec.elastic.co/v1/SecretPolicy#generationDate: "{{ now | isodate }}"
        template: |-
          {
            "privateKey": "{{ $sigKey := cryptoPair "ec" }}{{ $sigKey.Private | toPem | b64enc }}",
            "publicKey": "{{ $sigKey.Public | toPem | b64enc }}"
          }
