CertSafari
    Snowflake SnowPro Advanced: Security Engineer (SEA-C01)· Lessons

    Domain 5 · Lesson 19/21

    Snowpark Container Services: Ingress, Egress, Secrets and Monitoring

    Secure and govern applications with Snowpark Container Services.

    11 min read
    4% of exam
    5 sources
    Published 5 Oct 2026
    Docs as of 4 Oct 2026

    What you will be able to do

    • Explain the difference between private and public endpoints and what the Snowflake ingress proxy enforces
    • Configure controlled egress with egress network rules and an external access integration
    • Pass credentials into containers with Snowflake secrets instead of plain values in the specification
    • Choose the right tool for container logs and compute pool usage while giving out the least access

    1.Ingress: private by default, public through a proxy

    Every port a service listens on is declared as an endpoint in the specification. By default, endpoints are private. Only service functions and other services can call them. Setting public: true gives the endpoint a unique Snowflake hostname reachable from the internet. Because this is a privileged operation, the owner role must hold BIND SERVICE ENDPOINT on the account.

    Declaring a public endpoint in the service specificationyaml
    endpoints:
    - name: <endpoint name>
      port: <port number>
      protocol : < TCP / HTTP >
      public: true

    Public traffic never reaches your container directly. A Snowflake proxy sits in front of the service and filters both requests and responses. Idle connections are closed after 90 seconds, and users can sign out at /sfc-endpoint/logout, after which they have to authenticate to Snowflake again.

    What the ingress proxy does
    DirectionProxy behaviour
    RequestRefuses to forward the banned HTTP methods TRACE and CONNECT
    RequestRemoves X-SF-SPCS-Authorization, and removes Authorization when it contains a Snowflake token
    ResponseReturns 403 instead of an executable Content-Type such as application/x-sh
    ResponseRemoves the Server, X-Powered-By, X-XSS-Protection and Public-Key-Pins headers
    ResponseSets X-Frame-Options to DENY and X-Content-Type-Options to nosniff, and adds a Content-Security-Policy
    ResponseReturns the CORS settings from the specification and removes CORS headers sent by the service

    Checkpoint 1 of 7· Exam question

    A security engineer is drafting the VALUE_LIST for a network rule (MODE = EGRESS, TYPE = HOST_PORT) that will back an external access integration for a service. Which TWO entries are valid for Snowpark Container Services egress?(Select 2)

    Checkpoint 2 of 7· Check yourself

    A web app on a public SPCS endpoint returns CORS headers from its own code. A browser client still sees different CORS behaviour. Why?

    Sources1

    2.Egress: network rules and external access integrations

    Outbound access is the reverse problem. By default, services have only limited internet access. To allow a destination, an administrator creates one or more egress network rules and gathers them, together with any secrets, into an external access integration (EAI). The service is then configured to use that EAI. Any destination that no rule allows is denied. Snowflake gives ACCOUNTADMIN as an example of a role that can create an EAI. Creating a network rule requires CREATE NETWORK RULE on the schema.

    Checkpoint 3 of 7· Fill the gap

    Which MODE value makes this rule usable in an external access integration?

    CREATE OR REPLACE NETWORK RULE google_apis_network_rule
      MODE =  ? 
      TYPE = HOST_PORT
      VALUE_LIST = ('translation.googleapis.com');

    SPCS adds some limits. VALUE_LIST needs full host names, and wildcards such as *.googleapis.com are rejected. If you leave out the port, it defaults to 443. SPCS accepts only rules for ports 22, 80, 443 and 1024 and above. The EAI also applies to the browser: for a public web app, the proxy copies the EAI's network rules into the page's Content-Security-Policy, so the page can reach only the sites the service can reach.

    Checkpoint 4 of 7· Check yourself

    An engineer wants a service to call every Google API host and writes VALUE_LIST = ('*.googleapis.com'). What is the result for SPCS?

    Sources12

    3.Keeping secrets out of the YAML

    The containers.env field looks like an easy place for an API key, but every process in the container can read those variables, and the specification itself is metadata. Snowflake asks customers not to put personal, sensitive or regulated data there. The right approach is to store the credential in a Snowflake secret object and reference it from the specification.

    The containers.secrets block of the service specificationyaml
        secrets:                                # optional list
          - snowflakeSecret:
              objectName: <object-name>         # specify this or objectReference
              objectReference: <reference-name> # specify this or objectName
            directoryPath: <path>               # specify this or envVarName
            envVarName: <name>                  # specify this or directoryPath
            secretKeyRef: username | password | secret_string # specify only with envVarName

    snowflakeSecret names the secret with objectName. In a Native App with containers, it uses objectReference instead. You then choose where the value appears in the container: envVarName puts one key, chosen with secretKeyRef (username, password or secret_string), into an environment variable, and directoryPath writes the secret to files. The service's owner role needs READ on every secret it references, so access to secrets is controlled by grants rather than by whoever can read the YAML.

    Checkpoint 5 of 7· Check yourself

    CREATE SERVICE fails when the specification references a Snowflake secret through snowflakeSecret.objectName. Which grant is most likely missing?

    Sources3

    4.Monitoring: container logs and compute pool usage

    Unless you opt out, Snowflake collects whatever containers write to stdout and stderr into the account's event table. spec.logExporters chooses which streams are kept (all, stderr only, or none), and the LOG_LEVEL parameter on CREATE SERVICE or ALTER SERVICE sets the severity. Logs written as JSON with a body key are stored as structured records. Any other output goes into the value column. Anything the code prints ends up in a table, so do not log secrets.

    Three ways to read container logs, and the access each needs
    MethodWhat it returnsAccess consideration
    <service_name>!SPCS_GET_LOGSEvent-table logs for one service or job, one day by defaultService owner role or MONITOR on the service. No access to the whole event table is needed
    Query the event table directlyHistorical logs, filtered on RESOURCE_ATTRIBUTES such as snow.service.nameRequires full access to the event table
    SYSTEM$GET_SERVICE_LOGSLogs of a container that is currently running, not saved to the event tableMost useful during development and testing
    Querying the event table for one service's logs from the last hoursql
    SELECT TIMESTAMP, RESOURCE_ATTRIBUTES, RECORD_ATTRIBUTES, VALUE
    FROM <current_event_table_for_your_account>
    WHERE timestamp > dateadd(hour, -1, current_timestamp())
    AND RESOURCE_ATTRIBUTES:"snow.service.name" = '<service_name>'
    AND RECORD_TYPE = 'LOG'
    ORDER BY timestamp DESC
    LIMIT 10;

    For compute pools, the exam guide mentions a SERVICE_USAGE_HISTORY view. The documentation in these sources does not describe a view by that name. The pool-level view it does document is ACCOUNT_USAGE.SNOWPARK_CONTAINER_SERVICES_HISTORY. It returns hourly credits for each compute pool over 365 days, with up to three hours of latency, and its IS_EXCLUSIVE and APPLICATION_NAME columns show pools created for applications. An unexpected rise in a pool's credits is a signal worth investigating. Every monitoring method still requires the right privileges on the services, jobs and compute pools involved.

    Checkpoint 6 of 7· Exam question

    Which privilege must the owner role of a service hold before the service can be created with an endpoint declared as public: true in its specification?

    Checkpoint 7 of 7· Match them up

    Match each monitoring need to the tool that fits

    Tap a term, then the definition that fits it.

    Sources45

    Exam traps

    Each one states something that sounds right. Open it to see what is actually true.

    1. 1.A service endpoint can be reached from the internet unless you explicitly block it.Why is that wrong?

      Endpoints are private by default. Only service functions and other services can call them until public: true is set, and that requires BIND SERVICE ENDPOINT.

      Covered in Ingress: private by default, public through a proxy

    2. 2.To let someone read one service's logs, you have to grant them access to the account's event table.Why is that wrong?

      <service_name>!SPCS_GET_LOGS needs only the owner role or MONITOR on that service, so the rest of the event table stays restricted.

      Covered in Monitoring: container logs and compute pool usage

    3. 3.Putting an API key in containers.env is safe because only the main process reads it.Why is that wrong?

      Every process in the container can read env values, and specification metadata should not contain sensitive data. Use containers.secrets with a Snowflake secret instead.

      Covered in Keeping secrets out of the YAML

    Practise it for real

    Find and read a service's container logs while using as little access as possible

    1. 1.Run SHOW PARAMETERS LIKE 'event_table' IN ACCOUNT;

      Why: Container logs go to the account's active event table, so you need to know which table that is.

      You should see: The EVENT_TABLE parameter value, which is the fully qualified name of the active event table.

    2. 2.As a role with MONITOR on the service, run SELECT * FROM TABLE(mydb.myschema.my_test_job!SPCS_GET_LOGS());

      Why: This shows that log access can be limited to one service without opening the whole event table.

      You should see: Rows with TIMESTAMP, INSTANCE_ID, CONTAINER_NAME, LOG and RECORD_ATTRIBUTES for the past day.

    3. 3.As a role with full event table access, run the event-table query filtered on RESOURCE_ATTRIBUTES:"snow.service.name" and RECORD_TYPE = 'LOG'.

      Why: A direct query reaches historical logs and every resource attribute, but it requires broad access.

      You should see: Up to 10 log rows from the last hour, newest first.

    Stuck? Get a nudge

    If SPCS_GET_LOGS returns nothing, check whether spec.logExporters or LOG_LEVEL is filtering out the streams you expected.

    Sources

    Every claim above is drawn from one of these pages, quoted as it was written on the date shown.

    1. 1.
      “Creating a public endpoint is a privileged operation and the service’s owner role must have the BIND SERVICE ENDPOINT privilege on the account.”
      ↩︎ Ingress: private by default, public through a proxy
      “the proxy does not forward the request to your service: TRACE CONNECT”
      ↩︎ Ingress: private by default, public through a proxy
      “the Snowflake proxy sets this response header to DENY, preventing other web pages from using an iframe to the web page for your service.”
      ↩︎ Ingress: private by default, public through a proxy
      “If there is no activity on a connection to an ingress endpoint for 90 seconds, Snowflake terminates the connection.”
      ↩︎ Ingress: private by default, public through a proxy
      “By default, services have limited permissions to access the internet.”
      ↩︎ Egress: network rules and external access integrations
      “Snowpark Container Services supports only the network rules that allow ports 22, 80, 443, and 1024+.”
      ↩︎ Egress: network rules and external access integrations
      “The Snowflake proxy applies the same network restrictions on the service and the web page by adding a Content-Security-Policy (CSP) header in the response.”
      ↩︎ Egress: network rules and external access integrations
      “By default, service endpoints are private. Only service functions and service-to-service communications can make requests to the private endpoints.”
      ↩︎ Exam trap 1
      “Note that the proxy removes any CORS headers returned by the service.”
      ↩︎ Checkpoint
      “you must provide a full host name. Wildcards (for example, *.googleapis.com) are not supported.”
      ↩︎ Checkpoint
    2. 2.
      “An attempt to access a network location that is not specified by an allowed network rule will be denied.”
      ↩︎ Egress: network rules and external access integrations
      “If you omit a port number, Snowflake will use the default port number for external access, 443.”
      ↩︎ Egress: network rules and external access integrations
    3. 3.
      “Customers should ensure that no personal data, sensitive data, export-controlled data, or other regulated data is entered as metadata in the specification file.”
      ↩︎ Keeping secrets out of the YAML
      “Use the envVarName field to pass the secret as environment variables or directoryPath to write the secrets to local container files.”
      ↩︎ Keeping secrets out of the YAML
      “All processes in the container have access to these environment variables”
      ↩︎ Exam trap 3
      “Note that, the role that is creating the service (owner role) will need the READ privilege on the secrets referenced.”
      ↩︎ Checkpoint
    4. 4.
      “You control which streams are collected (all, standard error only, or none)”
      ↩︎ Monitoring: container logs and compute pool usage
      “A user needs the appropriate privileges on services, jobs, and compute pools to access the monitoring data.”
      ↩︎ Monitoring: container logs and compute pool usage
      “The caller needs either the service owner role or a role with the MONITOR privilege on the service.”
      ↩︎ Exam trap 2
      “The caller does not need access to the entire event table, which can be beneficial for customers with strict information-security requirements.”
      ↩︎ Checkpoint
    5. 5.
      “can be used to return the hourly compute pool credit usage for an account within the last 365 days (1 year).”
      ↩︎ Monitoring: container logs and compute pool usage

    Spotted a mistake, or was something unclear? Tell us.