Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SNOW-1335075: SNOW-1209099 Cannot connect using private key auth over private link with regionless account notation #489

Open
ehclark opened this issue Apr 18, 2024 · 1 comment
Assignees
Labels
bug Something isn't working status-in_progress Issue is worked on by the driver team status-triage_done Initial triage done, will be further handled by the driver team

Comments

@ehclark
Copy link

ehclark commented Apr 18, 2024

Please answer these questions before submitting your issue. Thanks!

  1. What version of Python are you using?

    Python 3.11.8 (main, Feb 6 2024, 21:21:21) [Clang 15.0.0 (clang-1500.1.0.2.5)]

  2. What operating system and processor architecture are you using?

    macOS-14.4.1-x86_64-i386-64bit

  3. What are the component versions in the environment (pip freeze)?

    annotated-types==0.6.0
    anyio==4.3.0
    asn1crypto==1.5.1
    asttokens==2.4.1
    attrs==23.2.0
    bandit==1.7.7
    -e git+https://github.com/biocommons/anyvar.git@ab96430665cbaa1697e3d69ea3a0b1ffb407ff95#egg=biocommons.anyvar
    biocommons.seqrepo==0.6.9
    bioutils==0.5.8.post1
    black==24.2.0
    canonicaljson==2.0.0
    certifi==2024.2.2
    cffi==1.16.0
    cfgv==3.4.0
    charset-normalizer==3.3.2
    click==8.1.7
    coloredlogs==15.0.1
    configparser==6.0.1
    coverage==7.4.3
    cryptography==41.0.7
    decorator==5.1.1
    dill==0.3.8
    distlib==0.3.8
    executing==2.0.1
    fastapi==0.110.0
    filelock==3.13.1
    ga4gh.vrs @ file:///workspaces/gdh/vrs-python
    greenlet==3.0.3
    gunicorn==21.2.0
    h11==0.14.0
    hgvs==1.5.4
    httpcore==1.0.4
    httpx==0.27.0
    humanfriendly==10.0
    identify==2.5.35
    idna==3.6
    importlib-metadata==7.0.1
    iniconfig==2.0.0
    ipython==8.22.1
    jedi==0.19.1
    markdown-it-py==3.0.0
    matplotlib-inline==0.1.6
    mdurl==0.1.2
    mypy-extensions==1.0.0
    nodeenv==1.8.0
    numpy==1.26.4
    packaging==23.2
    Parsley==1.3
    parso==0.8.3
    pathspec==0.12.1
    pbr==6.0.0
    pexpect==4.9.0
    platformdirs==3.11.0
    pluggy==1.4.0
    pre-commit==3.6.2
    prompt-toolkit==3.0.43
    psycopg==3.1.18
    psycopg-binary==3.1.18
    psycopg-pool==3.2.1
    psycopg2==2.9.9
    psycopg2-binary==2.9.9
    ptyprocess==0.7.0
    pure-eval==0.2.2
    pycparser==2.21
    pydantic==2.6.2
    pydantic_core==2.16.3
    Pygments==2.17.2
    PyJWT==2.8.0
    pyOpenSSL==23.3.0
    pysam==0.22.0
    pytest==8.0.2
    pytest-cov==4.1.0
    pytest-mock==3.12.0
    python-multipart==0.0.9
    pytz==2024.1
    PyYAML==6.0.1
    requests==2.31.0
    rich==13.7.0
    ruff==0.2.2
    six==1.16.0
    sniffio==1.3.1
    snowflake-connector-python==3.4.1
    snowflake-sqlalchemy==1.5.1
    sortedcontainers==2.4.0
    SQLAlchemy==1.4.51
    sqlparse==0.4.4
    stack-data==0.6.3
    starlette==0.36.3
    stevedore==5.2.0
    tabulate==0.9.0
    tomlkit==0.12.3
    tqdm==4.66.2
    traitlets==5.14.1
    typing_extensions==4.10.0
    urllib3==1.26.18
    uvicorn==0.27.1
    virtualenv==20.25.1
    wcwidth==0.2.13
    yoyo-migrations==8.2.0
    zipp==3.17.0

  4. What did you do?

from snowflake.sqlalchemy import URL
from sqlalchemy import create_engine

from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization

with open("rsa_key.p8", "rb") as key:
    p_key = serialization.load_pem_private_key(
        key.read(),
        password=None,
        backend=default_backend(),
    )

pkb = p_key.private_bytes(
    encoding=serialization.Encoding.DER,
    format=serialization.PrivateFormat.PKCS8,
    encryption_algorithm=serialization.NoEncryption(),
)

engine = create_engine(
    URL(
        account="mgb-mgbdev.privatelink",
        user="***REDACTED****",
    ),
    connect_args={
        "private_key": pkb,
    },
)

engine.connect()

Results in error snowflake.connector.errors.DatabaseError: 250001 (08001): None: Failed to connect to DB: mgb-mgbdev.privatelink.snowflakecomputing.com:443. JWT token is invalid. [45834078-d20d-4e94-b034-7dcbb157e096]

The root cause is that the SnowflakeDialect.create_connect_args() returning account=mgb, which in turns makes the subject of the JWT incorrect. Instead, the account should be mgb-mgbdev.

I have implemented a monkey patch to workaround the issue:

# Create a new pointer to the existing create_connect_args method
SnowflakeDialect._orig_create_connect_args = SnowflakeDialect.create_connect_args

# Define a new create_connect_args method that calls the original method
#   and then fixes the result so that the account name is not mangled
#   when using privatelink
def sf_create_connect_args_override(self, url: URL):

    # retval is tuple of empty array and dict ([], {})
    retval = self._orig_create_connect_args(url)

    # the dict has the options including the mangled account name
    opts = retval[1]
    if "host" in opts and "account" in opts and ".privatelink.snowflakecomputing.com" in opts["host"]:
        opts["account"] = opts["host"].split(".")[0]

    return retval

# Replace the create_connect_args method with the override
SnowflakeDialect.create_connect_args = sf_create_connect_args_override
@ehclark ehclark added bug Something isn't working needs triage labels Apr 18, 2024
@github-actions github-actions bot changed the title Cannot connect using private key auth over private link SNOW-1335075: Cannot connect using private key auth over private link Apr 18, 2024
@sfc-gh-dszmolka sfc-gh-dszmolka self-assigned this Apr 19, 2024
@sfc-gh-dszmolka
Copy link

hi - thanks for raising this. Indeed this is a known issue for a while and we're working on resolving it. Thank you for sharing your approach too !

As an alternative mitigation, the account locator version (xy12345.eu-central-1.privatelink) can be too used in the account field; it should work as the issue only seems to affect the regionless privatelink notation (myorg-myaccount.privatelink) account format.

@sfc-gh-dszmolka sfc-gh-dszmolka changed the title SNOW-1335075: Cannot connect using private key auth over private link SNOW-1335075: Cannot connect using private key auth over private link with regionless account notation Apr 19, 2024
@sfc-gh-dszmolka sfc-gh-dszmolka added status-in_progress Issue is worked on by the driver team status-triage_done Initial triage done, will be further handled by the driver team and removed needs triage labels Apr 19, 2024
@sfc-gh-dszmolka sfc-gh-dszmolka changed the title SNOW-1335075: Cannot connect using private key auth over private link with regionless account notation SNOW-1335075: SNOW-1209099 Cannot connect using private key auth over private link with regionless account notation Apr 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working status-in_progress Issue is worked on by the driver team status-triage_done Initial triage done, will be further handled by the driver team
Projects
None yet
Development

No branches or pull requests

2 participants