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

feat: track oidc token #1518

Closed
wants to merge 46 commits into from
Closed

feat: track oidc token #1518

wants to merge 46 commits into from

Conversation

david972
Copy link
Contributor

@david972 david972 commented Jul 10, 2021

Related issue

#397
@aeneasr

Proposed changes

NEW FEATURE: This patch add the possibility to retrieve the access and refresh token
It introduces a crypt/decrypt package
And a handle to get the tokens

Checklist

For the moment it's more a draft and test will be done later

Further comments

Copy link
Member

@aeneasr aeneasr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome, thank you for working on this! I have a couple of comments which we need to improve prior to merge :)

Makefile Outdated Show resolved Hide resolved
.gitignore Outdated Show resolved Hide resolved
crypt/crypt_aes.go Outdated Show resolved Hide resolved
driver/config/.schema/config.schema.json Outdated Show resolved Hide resolved
driver/config/config.go Outdated Show resolved Hide resolved
driver/config/config.go Outdated Show resolved Hide resolved
identity/handler.go Outdated Show resolved Hide resolved
identity/handler.go Outdated Show resolved Hide resolved
identity/handler.go Outdated Show resolved Hide resolved
identity/handler.go Outdated Show resolved Hide resolved
This feature introduce a crypt/decrypt package use for access/refresh token for now

Signed-off-by: David ALEXANDRE <david.alexandre@w6d.io>
Signed-off-by: David ALEXANDRE <david.alexandre@w6d.io>
remove useless handler
improve general identity handler
This feature introduce a crypt/decrypt package use for access/refresh token for now

Signed-off-by: David ALEXANDRE <david.alexandre@w6d.io>
Signed-off-by: David ALEXANDRE <david.alexandre@w6d.io>
remove useless handler
improve general identity handler
@david972
Copy link
Contributor Author

currently I put all code the general identity get but I planned to move it to elsewhere if the way is validated

I’ll update the tests later
For the documentation, I will need to know whether it is sufficient and where it will be better suited

@david972 david972 requested a review from aeneasr July 21, 2021 18:58
@aeneasr
Copy link
Member

aeneasr commented Jul 23, 2021

Thank you for the changes! I will be able to review them next week! :)

@aeneasr aeneasr added this to the v0.8.0-alpha.1 milestone Aug 1, 2021
@aeneasr
Copy link
Member

aeneasr commented Aug 3, 2021

I tried pushing some changes required for merging the PR to your fork & branch, but it appears that I am not allowed to do so 😕

% git push ...
ERROR: Permission to push denied to aeneasr.
fatal: could not read from the remote repository.

Please make sure that you have the correct access rights
and the repository exists.

But the good news is, giving access is easy! ☺️ All you need to do is enable write access for maintainers. Thank you! 😄

If the repository belongs to an organization, please add me for the project as a collaborator!

@david972
Copy link
Contributor Author

david972 commented Aug 3, 2021

just did it

harnash added a commit to Wikia/kratos that referenced this pull request Aug 3, 2021
# Conflicts:
#	contrib/quickstart/kratos/email-password/kratos.yml
#	go.mod
#	go.sum
@david972 david972 requested a review from zepatrik as a code owner August 4, 2021 12:54
@david972
Copy link
Contributor Author

david972 commented Aug 4, 2021

ok thank for the review

@david972
Copy link
Contributor Author

david972 commented Aug 4, 2021

I assume that I can add some unit test now

@aeneasr
Copy link
Member

aeneasr commented Aug 4, 2021

I still have a few items, wait a few more minutes .)

Copy link
Member

@aeneasr aeneasr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! Here are some ideas. I also pushed a few changes to the naming conventions. Of course, we still need lots of tests :)

I am on holiday on friday-sunday so I can either review it tomorrow again, or next week. This is now on my priority list to get merged :)

identity/handler.go Outdated Show resolved Hide resolved
cipher/aes.go Show resolved Hide resolved
cipher/aes.go Outdated Show resolved Hide resolved
driver/config/.schema/config.schema.json Outdated Show resolved Hide resolved
driver/config/config.go Outdated Show resolved Hide resolved
identity/handler.go Outdated Show resolved Hide resolved
identity/handler.go Outdated Show resolved Hide resolved
identity/handler.go Outdated Show resolved Hide resolved
identity/identity.go Outdated Show resolved Hide resolved
Comment on lines 51 to 52
EncryptedAccessToken []byte `json:"encrypted_access_token"`
EncryptedRefreshToken []byte `json:"encrypted_refresh_token"`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make these a string as []byte is base64 encoded by encoding/json

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did but I don't know why maybe a mistake on my side but wrap and unwrap the encrypted data goes wrong.

Copy link
Contributor Author

@david972 david972 Aug 14, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes just retried this and it did not work due to non-printable character

@aeneasr
Copy link
Member

aeneasr commented Aug 4, 2021

Looks like my comment partially didn't make it - the tests for the schema can be added here: https://github.com/ory/kratos/tree/master/test/schema

@david972
Copy link
Contributor Author

david972 commented Aug 4, 2021

ok I on the change try to do it before your holiday

@aeneasr
Copy link
Member

aeneasr commented Aug 4, 2021

awesome! :)

@david972
Copy link
Contributor Author

david972 commented Aug 11, 2021

Sorry I've got some personal issues
I'll try to do it for monday

Copy link
Member

@aeneasr aeneasr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello @david972 - this is some great stuff here! Good job! Sorry it took so long to review - cryptography just takes a lot of time to look into.

I have made a couple of adjustments, but nothing too critical. One important thing would be to move the github-app feature into a spearate PR.

Another thing is regarding the required secret. I was thinking about the impact on people getting started with Ory Kratos. I remember when we introduced this feature to Ory Hydra, it was very confusing to people at first. They often lost the keys, mixed them up, and in general had issues with managing encryption keys.

So I wonder if it would make sense to have one cypher which is a noop, and use that per default? That noop cipher would not need any secret and would be the default.

If you want tighter security, you would then use e.g. xchacha-poly1305.

What do you think about that?

selfservice/strategy/oidc/provider_github_app.go Outdated Show resolved Hide resolved
Makefile Outdated Show resolved Hide resolved
cipher/aes.go Show resolved Hide resolved
cipher/cipher_test.go Show resolved Hide resolved
driver/config/.schema/config.schema.json Outdated Show resolved Hide resolved
driver/config/.schema/config.schema.json Outdated Show resolved Hide resolved
driver/config/config.go Outdated Show resolved Hide resolved
@david972
Copy link
Contributor Author

Hello @david972 - this is some great stuff here! Good job! Sorry it took so long to review - cryptography just takes a lot of time to look into.

Thanks

I have made a couple of adjustments, but nothing too critical. One important thing would be to move the github-app feature into a spearate PR.

Another thing is regarding the required secret. I was thinking about the impact on people getting started with Ory Kratos. I remember when we introduced this feature to Ory Hydra, it was very confusing to people at first. They often lost the keys, mixed them up, and in general had issues with managing encryption keys.

So I wonder if it would make sense to have one cypher which is a noop, and use that per default? That noop cipher would not need any secret and would be the default.

If you want tighter security, you would then use e.g. xchacha-poly1305.

What do you think about that?

Yes that sound good too me to do. And actually it let people manage whether they want or not encrypting theirs data

If you give me you go I can do it very quickly

@aeneasr
Copy link
Member

aeneasr commented Aug 30, 2021

You have my go! :)

@david972
Copy link
Contributor Author

david972 commented Aug 30, 2021

An other point is regarding the schema validation that require the secret how can we set it as mandatory if people choose a cypher ?

@aeneasr
Copy link
Member

aeneasr commented Aug 30, 2021

It is possible with if/then - we have one example here: https://github.com/ory/kratos/blob/master/driver/config/.schema/config.schema.json#L1858

@aeneasr
Copy link
Member

aeneasr commented Aug 31, 2021

Ah and please don't forget to add the new docs page to the sidebar :)

https://github.com/ory/kratos/blob/master/docs/sidebar.json

@david972
Copy link
Contributor Author

you right I had forgotten

@david972
Copy link
Contributor Author

david972 commented Aug 31, 2021

right now I fight with schema 😉

update sidebar docs
improve schema validation and add test
remove use less statement from Makefile
@aeneasr
Copy link
Member

aeneasr commented Sep 11, 2021

@david972 currently on vacation, but will try to give it a review as soon as I have some stable internet :)

Copy link
Member

@aeneasr aeneasr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great stuff! We’re very close :)

cipher/cipher_test.go Show resolved Hide resolved
cipher/noop.go Outdated Show resolved Hide resolved
cipher/noop.go Outdated Show resolved Hide resolved
docs/docs/guides/reveal-credentials.md Outdated Show resolved Hide resolved
driver/config/.schema/config.schema.json Outdated Show resolved Hide resolved
selfservice/strategy/oidc/types.go Outdated Show resolved Hide resolved
selfservice/strategy/oidc/types.go Outdated Show resolved Hide resolved
Subject string `json:"subject"`
Provider string `json:"provider"`
EncryptedAccessToken string `json:"encrypted_access_token"`
EncryptedRefreshToken string `json:"encrypted_refresh_token"`
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe add initial_id_token too?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What will this refer to ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some systems issue an ID Token alongside the access_token. It will be available as id_token if set. Some applications might want to use this to perform additional checks! In general, this refers to OpenID Connect :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok got it

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I saw that the id token is a jet that may contain audience and nonce. So that mean we should encrypt it as well


func (i *Identity) getOIDCToken(r *http.Request, c cipher.Provider) error {
for credType, credential := range i.Credentials {
if credType != CredentialsTypeOIDC {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is perfect- I just think you don’t need a new struct! Use what we already have with the credentials struct :)

chore: comment useless type
feat: move credential in credentials
@david972
Copy link
Contributor Author

david972 commented Oct 3, 2021

Hi as discussed here is my proposal
@aeneasr
currently

curl http://localhost:4434/identities/2587dd42-4530-4bc9-b04c-07070f32b88e
{
  "id": "2587dd42-4530-4bc9-b04c-07070f32b88e",
  "credentials": {
    "oidc": {
      "type": "oidc",
      "identifiers": [
        "w6d-kratos-oauth2:9482408"
      ],
      "access_token": "gho_xxxxxxxxxxxxxxxxxxxxxx",
      "created_at": "2021-09-29T19:12:48.477763Z",
      "updated_at": "2021-09-29T19:12:48.477763Z"
    },
    "password": {
      "type": "password",
      "identifiers": [
        "david.alexandre@w6d.io"
      ],
      "created_at": "2021-09-29T19:12:48.481521Z",
      "updated_at": "2021-09-29T19:12:48.481521Z"
    }
  },
...

after

{
  "id": "2587dd42-4530-4bc9-b04c-07070f32b88e",
  "credentials": {
    "oidc": {
      "type": "oidc",
      "identifiers": [
        {
          "provider": "github",
          "subject":"9482408",
          "access_token": "gho_xxxxxxxxxx"
        }
      ],
      "created_at": "2021-09-29T19:12:48.477763Z",
      "updated_at": "2021-09-29T19:12:48.477763Z"
    },
    "password": {
      "type": "password",
      "identifiers": [
        {
          "username":"david.alexandre@w6d.io"
        }
      ],
      "created_at": "2021-09-29T19:12:48.481521Z",
      "updated_at": "2021-09-29T19:12:48.481521Z"
    }
  },
...
}

@aeneasr
Copy link
Member

aeneasr commented Oct 8, 2021

@david972 I had some time and was able to complete the API changes :) See here: 1c722ff

It follows your proposal!

@david972
Copy link
Contributor Author

@david972 I had some time and was able to complete the API changes :) See here: 1c722ff

It follows your proposal!

great

Just one thing
If I do

curl 'http://localhost:4434/identities/2587dd42-4530-4bc9-b04c-07070f32b88e'
{
  "id": "2587dd42-4530-4bc9-b04c-07070f32b88e",
  "credentials": {
    "oidc": {
      "type": "oidc",
      "identifiers": [
        "w6d-kratos-oauth2:9482408",
        "w6d-kratos-test:9482408"
      ],
      "created_at": "2021-09-29T19:12:48.477763Z",
      "updated_at": "2021-10-08T20:29:49.946745Z"
    },
    "password": {
      "type": "password",
      "identifiers": [
        "david.alexandre@w6d.io"
      ],
      "created_at": "2021-09-29T19:12:48.481521Z",
      "updated_at": "2021-10-08T20:29:49.943148Z"
    }
  },
  "schema_id": "default",
  "schema_url": "http://127.0.0.1:4433/schemas/default",
  "state": "active",
  "traits": {
    "name": {
      "last": "ALEXANDRE",
      "first": "David"
    },
    "email": "david.alexandre@w6d.io"
  },
  "verifiable_addresses": [
    {
      "id": "1c9b6016-7325-493f-bd34-9daa1110ad9d",
      "value": "david.alexandre@w6d.io",
      "verified": false,
      "via": "email",
      "status": "sent",
      "created_at": "2021-09-29T19:12:48.472902Z",
      "updated_at": "2021-10-08T20:29:49.938865Z"
    }
  ],
  "recovery_addresses": [
    {
      "id": "cf7afd7a-d092-439d-a360-108408ccfc5c",
      "value": "david.alexandre@w6d.io",
      "via": "email",
      "created_at": "2021-09-29T19:12:48.475019Z",
      "updated_at": "2021-10-08T20:29:49.940551Z"
    }
  ],
  "created_at": "2021-09-29T19:12:48.47087Z",
  "updated_at": "2021-09-29T19:12:48.47087Z"
}

but the password part disappear if I do

curl 'http://localhost:4434/identities/2587dd42-4530-4bc9-b04c-07070f32b88e?include_credential=oidc'
{
  "id": "2587dd42-4530-4bc9-b04c-07070f32b88e",
  "credentials": {
    "oidc": {
      "type": "oidc",
      "identifiers": [
        "w6d-kratos-oauth2:9482408",
        "w6d-kratos-test:9482408"
      ],
      "config": {
        "providers": [
          {
            "initial_id_token": "",
            "subject": "9482408",
            "provider": "w6d-kratos-oauth2",
            "initial_access_token": "gho_xxxxxxxxxx",
            "initial_refresh_token": ""
          },
          {
            "initial_id_token": "",
            "subject": "9482408",
            "provider": "w6d-kratos-test",
            "initial_access_token": "ghu_xxxxxxxxxx",
            "initial_refresh_token": "ghr_xxxxxxxxxx"
          }
        ]
      },
      "created_at": "2021-09-29T19:12:48.477763Z",
      "updated_at": "2021-10-08T20:29:49.946745Z"
    }
  },
  "schema_id": "default",
  "schema_url": "http://127.0.0.1:4433/schemas/default",
  "state": "active",
  "traits": {
    "name": {
      "last": "ALEXANDRE",
      "first": "David"
    },
    "email": "david.alexandre@w6d.io"
  },
  "verifiable_addresses": [
    {
      "id": "1c9b6016-7325-493f-bd34-9daa1110ad9d",
      "value": "david.alexandre@w6d.io",
      "verified": false,
      "via": "email",
      "status": "sent",
      "created_at": "2021-09-29T19:12:48.472902Z",
      "updated_at": "2021-10-08T20:29:49.938865Z"
    }
  ],
  "recovery_addresses": [
    {
      "id": "cf7afd7a-d092-439d-a360-108408ccfc5c",
      "value": "david.alexandre@w6d.io",
      "via": "email",
      "created_at": "2021-09-29T19:12:48.475019Z",
      "updated_at": "2021-10-08T20:29:49.940551Z"
    }
  ],
  "created_at": "2021-09-29T19:12:48.47087Z",
  "updated_at": "2021-09-29T19:12:48.47087Z"
}

I understand that the password should not appear but I expected at least to see the same information

@aeneasr
Copy link
Member

aeneasr commented Oct 11, 2021

Yeah, that makes sense!

@aeneasr aeneasr mentioned this pull request Oct 12, 2021
aeneasr added a commit that referenced this pull request Oct 12, 2021
…1818)

This patch introduces the new `include_credential` query parameter to the `GET /identities` endpoint which allows administrators to receive the initial access, refresh, and ID tokens from Social Sign In (OpenID Connect / OAuth 2.0) flows.

These tokens can be stored in an encrypted format (XChaCha20Poly1305 or AES-GCM) in the database if an appropriate encryption secret is set. To get started easily these values are not encrypted per default.

For more information head [over to the docs](https://kratos/docs/guides/retrieve-social-sign-in-access-refresh-id-token).

Closes #1518
Closes #397
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants