#
# Managed by Puppet
#
authorization: {
    version: 1
    allow-header-cert-info: <%= @server_http || @allow_header_cert_info %>
    rules: [
        {
            # Allow nodes to retrieve their own catalog
            match-request: {
                path: "^/puppet/v3/catalog/([^/]+)$"
                type: regex
                method: [get, post]
            }
<%= scope.call_function(
  'to_json_pretty',
  [
    {'allow' => @server_trusted_agents + ['$1'] + @server_trusted_certificate_extensions.map { |extension| { 'extensions' => extension } } }
  ]
).lines.to_a[1..-2].map{ |line| "          #{line}"}.join
-%>
            sort-order: 500
            name: "puppetlabs v3 catalog from agents"
        },
        {
            # Allow services to retrieve catalogs on behalf of others
            match-request: {
                path: "^/puppet/v4/catalog/?$"
                type: regex
                method: post
            }
<%- if @server_trusted_agents.empty? && @server_trusted_certificate_extensions.empty? -%>
            deny: "*"
<%- else -%>
<%= scope.call_function(
  'to_json_pretty',
  [
    {'allow' => @server_trusted_agents + @server_trusted_certificate_extensions.map { |extension| { 'extensions' => extension } } }
  ]
).lines.to_a[1..-2].map{ |line| "          #{line}"}.join
-%>
<%- end -%>
            sort-order: 500
            name: "puppetlabs v4 catalog for services"
        },
        {
            # Allow nodes to retrieve the certificate they requested earlier
            match-request: {
                path: "/puppet-ca/v1/certificate/"
                type: path
                method: get
            }
            allow-unauthenticated: true
            sort-order: 500
            name: "puppetlabs certificate"
        },
        {
            # Allow all nodes to access the certificate revocation list
            match-request: {
                path: "/puppet-ca/v1/certificate_revocation_list/ca"
                type: path
                method: get
            }
            allow-unauthenticated: true
            sort-order: 500
            name: "puppetlabs crl"
        },
        {
            # Allow nodes to request a new certificate
            match-request: {
                path: "/puppet-ca/v1/certificate_request"
                type: path
                method: [get, put]
            }
            allow-unauthenticated: true
            sort-order: 500
            name: "puppetlabs csr"
        },
<%- if @server_ca -%>
        {
            # Allow the CA CLI to access the certificate_status endpoint
            match-request: {
                path: "/puppet-ca/v1/certificate_status"
                type: path
                method: [get, put, delete]
            }
<%- if @server_ca_auth_required == false -%>
            allow-unauthenticated: true
<%- else -%>
            allow: [
<%- @server_ca_client_allowlist.each do |client| -%>
                "<%= client %>",
<%- end -%>
                {
                    extensions: {
                        pp_cli_auth: "true"
                    }
                }
            ]
<%- end -%>
            sort-order: 500
            name: "puppetlabs cert status"
        },
        {
            match-request: {
                path: "^/puppet-ca/v1/certificate_revocation_list$"
                type: regex
                method: put
            }
            allow: {
               extensions: {
                   pp_cli_auth: "true"
               }
            }
            sort-order: 500
            name: "puppetlabs CRL update"
        },
        {
            # Allow the CA CLI to access the certificate_statuses endpoint
            match-request: {
                path: "/puppet-ca/v1/certificate_statuses"
                type: path
                method: get
            }
<%- if @server_ca_auth_required == false -%>
            allow-unauthenticated: true
<%- else -%>
            allow: [
<%- @server_ca_client_allowlist.each do |client| -%>
                "<%= client %>",
<%- end -%>
                {
                    extensions: {
                        pp_cli_auth: "true"
                    }
                }
            ]
<%- end -%>
            sort-order: 500
            name: "puppetlabs cert statuses"
        },
<%- if @server_ca_client_self_delete -%>
        {
            name: "Allow nodes to delete their own certificates",
            match-request: {
                path: "^/puppet-ca/v1/certificate(_status|_request)?/([^/]+)$"
                type: regex
                method: [delete]
            },
            allow: [
                "$2",
<%- @server_admin_api_allowlist.each do |client| -%>
                "<%= client %>",
<%- end -%>
                {
                    extensions: {
                        pp_cli_auth: "true"
                    }
                }
            ]
            sort-order: 500
        },
<%- end -%>
<%- end -%>
        {
            # Allow authenticated access to the CA expirations endpoint
            match-request: {
                path: "/puppet-ca/v1/expirations"
                type: path
                method: get
            }
            allow: "*"
            sort-order: 500
            name: "puppetlabs CA cert and CRL expirations"
        },
        {
            # Allow the CA CLI to access the certificate clean endpoint
            match-request: {
                path: "/puppet-ca/v1/clean"
                type: path
                method: put
            }
            allow: {
               extensions: {
                   pp_cli_auth: "true"
               }
            }
            sort-order: 500
            name: "puppetlabs cert clean"
        },
        {
            # Allow unauthenticated access to the status service endpoint
            match-request: {
                path: "/status/v1/services"
                type: path
                method: get
            }
            allow-unauthenticated: true
            sort-order: 500
            name: "puppetlabs status service - full"
        },
        {
            match-request: {
                path: "/status/v1/simple"
                type: path
                method: get
            }
            allow-unauthenticated: true
            sort-order: 500
            name: "puppetlabs status service - simple"
        },
        {
            match-request: {
                path: "/puppet-admin-api/v1/environment-cache"
                type: path
                method: delete
            }
            allow: [
<%- @server_admin_api_allowlist.each do |client| -%>
                "<%= client %>",
<%- end -%>
            ]
            sort-order: 200
            name: "environment-cache"
        },
        {
            match-request: {
                path: "/puppet-admin-api/v1/jruby-pool"
                type: path
                method: delete
            }
            allow: [
<%- @server_admin_api_allowlist.each do |client| -%>
                "<%= client %>",
<%- end -%>
            ]
            sort-order: 200
            name: "jruby-pool"
        },
        {
            match-request: {
                path: "/puppet/v3/environments"
                type: path
                method: get
            }
            allow: "*"
            sort-order: 500
            name: "puppetlabs environments"
        },
        {
            match-request: {
                path: "/puppet/v3/environment_classes"
                type: path
                method: get
            }
            allow: "*"
            sort-order: 500
            name: "puppetlabs environment classes"
        },
        {
            # Allow nodes to access all file_bucket_files.  Note that access for
            # the 'delete' method is forbidden by Puppet regardless of the
            # configuration of this rule.
            match-request: {
                path: "/puppet/v3/file_bucket_file"
                type: path
                method: [get, head, post, put]
            }
            allow: "*"
            sort-order: 500
            name: "puppetlabs file bucket file"
        },
        {
            # Allow nodes to access all file_content.  Note that access for the
            # 'delete' method is forbidden by Puppet regardless of the
            # configuration of this rule.
            match-request: {
                path: "/puppet/v3/file_content"
                type: path
                method: [get, post]
            }
            allow: "*"
            sort-order: 500
            name: "puppetlabs file content"
        },
        {
            # Allow nodes to access all file_metadata.  Note that access for the
            # 'delete' method is forbidden by Puppet regardless of the
            # configuration of this rule.
            match-request: {
                path: "/puppet/v3/file_metadata"
                type: path
                method: [get, post]
            }
            allow: "*"
            sort-order: 500
            name: "puppetlabs file metadata"
        },
        {
            # Allow nodes to retrieve only their own node definition
            match-request: {
                path: "^/puppet/v3/node/([^/]+)$"
                type: regex
                method: get
            }
            allow: "$1"
            sort-order: 500
            name: "puppetlabs node"
        },
        {
            # Allow nodes to store only their own reports
            match-request: {
                path: "^/puppet/v3/report/([^/]+)$"
                type: regex
                method: put
            }
            allow: "$1"
            sort-order: 500
            name: "puppetlabs report"
        },
        {
            # Allow nodes to update their own facts
            match-request: {
                path: "^/puppet/v3/facts/([^/]+)$"
                type: regex
                method: put
            }
            allow: "$1"
            sort-order: 500
            name: "puppetlabs facts"
        },
        {
            match-request: {
                path: "/puppet/v3/static_file_content"
                type: path
                method: get
            }
            allow: "*"
            sort-order: 500
            name: "puppetlabs static file content"
        },
        {
            match-request: {
                path: "/puppet/v3/tasks"
                type: path
            }
            allow: "*"
            sort-order: 500
            name: "puppet tasks information"
        },
<%- if @server_experimental -%>
        {
            # Allow all users access to the experimental endpoint
            # which currently only provides a dashboard web ui.
            match-request: {
                path: "/puppet/experimental"
                type: path
            }
            allow-unauthenticated: true
            sort-order: 500
            name: "puppetlabs experimental"
        },
<%- end -%>
<%- unless @jolokia_metrics_allowlist.empty? -%>
        {
            match-request: {
                path: "/metrics/v2"
                type: path
            }
            allow: [
<%- @jolokia_metrics_allowlist.each do |client| -%>
                "<%= client %>",
<%- end -%>
            ]
            sort-order: 500
            name: "jolokia metrics"
        },
<%- end -%>
        {
            # Deny everything else. This ACL is not strictly
            # necessary, but illustrates the default policy
            match-request: {
                path: "/"
                type: path
            }
            deny: "*"
            sort-order: 999
            name: "puppetlabs deny all"
        }
    ]
}
