Hi, I just ran Ory Kratos in local and tested it s...
# talk-kratos
d
Hi, I just ran Ory Kratos in local and tested it successfully. But, when I tried to run it on a Kubernetes cluster, I get
ERR_TOO_MANY_REDIRECTS
I changed lots of configs, but couldn’t fix that.
my helm values:
Copy code
kratos:
  autoMigrate: true
  config:
    version: v0.8.0-alpha.3
    dsn: REDACTED
    serve:
      public:
        base_url: <https://auth.foo.bar>
        cors:
          enabled: true
      admin:
        base_url: <https://auth-admin.foo.bar>
    courier:
      smtp:
        connection_uri: REDACTED
        from_name: John Doe
        from_address: noreply@foo.bar
    selfservice:
      default_browser_return_url: <https://accounts.foo.bar>
      flows:
        error:
          ui_url: <https://accounts.foo.bar/error>
        settings:
          ui_url: <https://accounts.foo.bar/settings>
        login:
          ui_url: <https://accounts.foo.bar/login>
        registration:
          ui_url: <https://accounts.foo.bar/registration>
          after:
            password:
              hooks:
                - hook: session
        recovery:
          enabled: true
          ui_url: <https://accounts.foo.bar/recovery>
        verification:
          enabled: true
          ui_url: <https://accounts.foo.bar/verify>
    log:
      leak_sensitive_values: true
    identity:
      default_schema_url: file:///etc/config/identity.schema.json
  identitySchemas:
    "identity.schema.json": |
      {
        "$id": "<https://schemas.ory.sh/presets/kratos/quickstart/email-password/identity.schema.json>",
        "$schema": "<http://json-schema.org/draft-07/schema#>",
        "title": "Person",
        "type": "object",
        "properties": {
          "traits": {
            "type": "object",
            "properties": {
              "email": {
                "type": "string",
                "format": "email",
                "title": "E-Mail",
                "minLength": 3,
                "<http://ory.sh/kratos|ory.sh/kratos>": {
                  "credentials": {
                    "password": {
                      "identifier": true
                    }
                  },
                  "verification": {
                    "via": "email"
                  },
                  "recovery": {
                    "via": "email"
                  }
                }
              },
              "name": {
                "type": "object",
                "properties": {
                  "first": {
                    "title": "First Name",
                    "type": "string"
                  },
                  "last": {
                    "title": "Last Name",
                    "type": "string"
                  }
                }
              }
            },
            "required": [
              "email"
            ],
            "additionalProperties": false
          }
        }
      }

ingress:
  admin:
    enabled: true
    className: nginx
    hosts:
      - host: auth-admin.foo.bar
        paths:
          - path: /
            pathType: ImplementationSpecific
    tls:
      - secretName: foo-bar-tls
        hosts:
          - auth-admin.foo.bar
  public:
    enabled: true
    className: nginx
    hosts:
      - host: auth.foo.bar
        paths:
          - path: /
            pathType: ImplementationSpecific
    tls:
      - secretName: foo-bar-tls
        hosts:
          - auth.foo.bar
secure app values:
Copy code
ingress:
  enabled: true
  className: nginx
  hosts:
    - host: accounts.foo.bar
      paths:
        - path: /
          pathType: ImplementationSpecific
  tls:
    - secretName: foo-bar-tls
      hosts:
        - accounts.foo.bar

kratosBrowserUrl: "<https://auth.foo.bar>"
kratosPublicUrl: "<https://auth.foo.bar>"
kratosAdminUrl: "<https://auth-admin.foo.bar>"
baseUrl: "/"
j
This is likely to be a cookie issue
1
d
I know that but I couldn’t fix that, so I sent my configs here 😄
j
If you cURL the public api endpoint you can see the cookie it's trying to set. It looks like you want to to be set on
foo.bar
,
I went through exactly the same thing
d
where I set that in my config? 🤔
j
in the reference config comment it's shown in
Session Cookie Domain
so config session cookie domain
d
so I should set session.cookie.domain to foo.bar?
j
change that, and curl the public api and see if it changes where the cookie is set
d
let me do it
j
I also have something in
domain_aliases
but I think that's because ultimately we gave up using multiple domains
d
why domain aliases?
j
I think because you are using multiple domains
d
no, I just use subdomains
j
that's what I mean
you have two separate sub domains right?
d
aha, so I have to use domain aliases?
j
one for the web app and one for the public api
I think so
but
it was way easier to have the setup like they have it in their examples, where the public api is on the same domain in
/public/api
d
yes, auth.foo.bar auth-admin.foo.bar & accounts.foo.bar
you mean using subdirectories instead of subdomains?
j
I bet if you curl the public api endpoint it's being set on which ever is the public api, which is therefore not valid on the web app
yes
Can you do that with an nginx ingress?
There was one complication with our setup there, and that is that whatever is being used to reverse proxy it (in your case nginx) needs to strip out the first part of the url `/api/public`before sending it on to the public api.
The truth is that we ended up using oathkeeper because it makes that setup really trivial
d
what should I check when I curl public api?
j
I can't remember exactly, I think it's the first url to start a flow
d
you mean this?
<https://accounts.foo.bar/registration?flow=b30db8d1-9cf4-4661-87d9-dd80c33c0b22>
j
Just looking now
I think it's
/api/public/self-service/login/api
so in your case you maybe don't need the api/public/
you want to be able to see the cookie so
curl -v
or maybe use a web browser and look in the inspector
d
Copy code
➜  curl -v -s -X GET \
-H "Accept: application/json" \
<https://auth.foo.bar/self-service/login/api>
*   Trying 104.21.13.44...
* TCP_NODELAY set
* Connected to auth.foo.bar (104.21.13.44) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/cert.pem
CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-ECDSA-CHACHA20-POLY1305
* ALPN, server accepted to use h2
* Server certificate:
*  subject: C=US; ST=California; L=San Francisco; O=Cloudflare, Inc.; CN=<http://sni.cloudflaressl.com|sni.cloudflaressl.com>
*  start date: Jul  1 00:00:00 2021 GMT
*  expire date: Jun 30 23:59:59 2022 GMT
*  subjectAltName: host "auth.foo.bar" matched cert's "*.foo.bar"
*  issuer: C=US; O=Cloudflare, Inc.; CN=Cloudflare Inc ECC CA-3
*  SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x7fc491810a00)
> GET /self-service/login/api HTTP/2
> Host: auth.foo.bar
> User-Agent: curl/7.64.1
> Accept: application/json
>
* Connection state changed (MAX_CONCURRENT_STREAMS == 256)!
< HTTP/2 200
< date: Thu, 06 Jan 2022 16:54:14 GMT
< content-type: application/json; charset=utf-8
< content-length: 1331
< cache-control: private, no-cache, no-store, must-revalidate
< vary: Origin
< vary: Cookie
< strict-transport-security: max-age=15724800; includeSubDomains
< cf-cache-status: DYNAMIC
< expect-ct: max-age=604800, report-uri="<https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct>"
< report-to: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v3?s=8bdT4jBfLjGvDUQtrPTpvhd4oubBqXP6OJyBEP7%2FcKCGEACyrvm2nOdjdvjj7NdSq%2FTp0cQrG%2FXFDQkGYWIWmAk3FX2Gbh5zNypNgIZ2oHgfKM8V7hmdItZi8nG7C88PSelCIUqxNVoZ6Q%3D%3D"}],"group":"cf-nel","max_age":604800}
< nel: {"success_fraction":0,"report_to":"cf-nel","max_age":604800}
< server: cloudflare
< cf-ray: 6c967795d9bf4e31-FRA
< alt-svc: h3=":443"; ma=86400, h3-29=":443"; ma=86400, h3-28=":443"; ma=86400, h3-27=":443"; ma=86400
<
{"id":"a4846c45-d587-4c45-8dc5-b151e23d8cbb","type":"api","expires_at":"2022-01-06T17:54:14.720544901Z","issued_at":"2022-01-06T16:54:14.720544901Z","request_url":"<http://auth.foo.bar/self-service/login/api>","ui":{"action":"<https://auth.foo.bar/self-service/login?flow=a4846c45-d587-4c45-8dc5-b151e23d8cbb>","method":"POST","nodes":[{"type":"input","group":"default","attributes":{"name":"csrf_token","type":"hidden","value":"","required":true,"disabled":false,"node_type":"input"},"messages":[],"meta":{}},{"type":"input","group":"password","attributes":{"name":"password_identifier","type":"text","value":"","required":true,"disabled":false,"node_type":"input"},"messages":[],"meta":{"label":{"id":1070004,"text":"ID","type":"info"}}},{"type":"input","group":"password","attributes":{"name":"password","type":"password","required":true,"disabled":false,"node_type":"input"},"messages":[],"meta":{"label":{"id":1070001,"text":"Password","type":"info"}}},{"type":"input","group":"password","attributes":{"name":"method","type":"submit","value":"password","disabled":false,"node_type":"input"},"messages":[],"meta":{"label":{"id":1010001,"text":"Sign in","type":"info","context":{}}}}]},"created_at":"2022-01-06T16:54:14.72626Z","updated_at":"2022-01-06T16:54:14.72626Z","refresh":false,"requested_aal":"aal1"}
* Connection #0 to host auth.foo.bar left intact
* Closing connection 0
I found that
request_url
is http not https. maybe its this the problem, huh?
Also, I use browser based flow, not api based
j
ah sorry
what happens when you use browser?
d
redirect loop between 2 addresses
j
so
Copy code
curl -v -s -X GET \
-H "Accept: application/json" \
<https://auth.foo.bar/self-service/login/browser>
look for a set-cookie response header
d
< set-cookie: csrf_token_2edd7809834ad40adb6feb3276519cec29d23dd2b32dad7191ed49fffbc38121=frFDDEhMXY4puQWIwX396ibn9p/brJgK2F/8r9iSScM=; Path=/; Max-Age=31536000; HttpOnly; Secure; SameSite=Lax
j
so it's got no domain set on it
d
did I misconfigure?
j
so it will only count for the domain you got it from I imagine
yes there is a missing setting somewhere, you need it to include the domain like this:
Path=/; Domain=foo.bar; Max-Age=31536000; HttpOnly; Secure; SameSite=Lax
d
I set
session.cookie.domain
to
foo.bar
but it doesn’t care 😄
j
yeah so there must be something else
d
it sets cookie on subdomains
j
this is why it's easier to have the web app and the public api on the same domain
d
it’s harder or impossible to use subdomains?
j
It's not impossible
we had it working
so in the helm values you have
kratos > config > session > cookie > domain
set?
d
yes
also
cookies.domain
set
also
domain_aliases
set 😄
j
I give up then haha
I would just mess with the config until I can get the csrf cookie to be set on the right domain
d
btw thanks for your time
j
thank you
❤️ 1
d
my cookie doesn’t have Domain as you mentioned https://ory-community.slack.com/archives/C012RJ2MQ1H/p1641488950015100?thread_ts=1641482797.004000&amp;cid=C012RJ2MQ1H so I should find a way to set that on root domain, huh?
j
it is not that clear what each of the 3 places in the config relate to when you set it up. It will be something to do with the
session > cookie
, the
domain_aliases
and the
cookies
👍 1
d
maybe I have to check source code…
j
in ours the
cookies
is set to the web app. a domain alias is set to the web app but with a base path of /api/public and the match_domain as the web app domain, and the session > cookie is set to the root domain
good luck
🙏 1
d
gave up, couldn’t run on kubernetes successfully, neither subdomain nor subpath.
@User any idea?
h
If you have a hard time getting it to work yourself, you can try Ory Cloud (https://console.ory.sh). We have an onboarding program where you get the first year for free with custom domain. I’d recommend that route if you’re stuck in your own deployment
d
I guessed you suggests cloud version 😅 I just trying to find an open source identity and authentication project to use. As you mentioned there is no enterprise feature and all of Ory products are open source. I guess we should improve the documentations to make it easier to use. Your answer is like a marketing trap 😊
h
It’s not a marketing trap, just try the product in cloud. See if it fits your use case. You can later still deploy it yourself. If redirects don’t work or are looping it means you have configured something incorrectly. But it’s incredibly hard to tell you what exactly because I don’t have access to your system
1
In Cloud we have taken care of everything and you don’t need to figure out deployment to see if the product works. It’s still open source, it’s the same code base we have in the github 🙂
d
I’m not a business. Just a developer who tries to start a business, so Cloud version doesn’t work for me now. I’ll try again and if get successful, will contribute to the documentations. Forget my quote about marketing trap ❤️
h
s
@User
a
Copy code
# Settings for both anti-CSRF and session cookies
cookies:
  domain: <http://www.cookies.com|www.cookies.com>
  path: /cookies
  same_site: Lax
I added #cookies to the kratos yaml akkording to https://www.ory.sh/kratos/docs/guides/multi-domain-cookies/#cookies
s
@User
👍 1
157 Views