diff --git a/providers/apple/apple.go b/providers/apple/apple.go
index b0e870a2c..c5e32a280 100644
--- a/providers/apple/apple.go
+++ b/providers/apple/apple.go
@@ -117,6 +117,8 @@ func (Provider) UnmarshalSession(data string) (goth.Session, error) {
 // as the only identifying attribute.
 // A full name and email can be obtained from the form post response
 // to the redirect page following authentication, if the name are email scopes are requested.
+// Additionally, if the response type is form_post and the email scope is requested, the email
+// will be encoded into the ID token in the email claim.
 func (p Provider) FetchUser(session goth.Session) (goth.User, error) {
 	s := session.(*Session)
 	if s.AccessToken == "" {
@@ -125,6 +127,7 @@ func (p Provider) FetchUser(session goth.Session) (goth.User, error) {
 	return goth.User{
 		Provider:     p.Name(),
 		UserID:       s.ID.Sub,
+		Email:        s.ID.Email,
 		AccessToken:  s.AccessToken,
 		RefreshToken: s.RefreshToken,
 		ExpiresAt:    s.ExpiresAt,
diff --git a/providers/apple/session.go b/providers/apple/session.go
index 1e401db94..d5c6e259e 100644
--- a/providers/apple/session.go
+++ b/providers/apple/session.go
@@ -20,7 +20,9 @@ const (
 )
 
 type ID struct {
-	Sub string `json:"sub"`
+	Sub            string `json:"sub"`
+	Email          string `json:"email"`
+	IsPrivateEmail bool   `json:"is_private_email"`
 }
 
 type Session struct {
@@ -47,6 +49,8 @@ type IDTokenClaims struct {
 	jwt.StandardClaims
 	AccessTokenHash string `json:"at_hash"`
 	AuthTime        int    `json:"auth_time"`
+	Email           string `json:"email"`
+	IsPrivateEmail  bool   `json:"is_private_email,string"`
 }
 
 func (s *Session) Authorize(provider goth.Provider, params goth.Params) (string, error) {
@@ -112,7 +116,9 @@ func (s *Session) Authorize(provider goth.Provider, params goth.Params) (string,
 			return "", err
 		}
 		s.ID = ID{
-			Sub: idToken.Claims.(*IDTokenClaims).Subject,
+			Sub:            idToken.Claims.(*IDTokenClaims).Subject,
+			Email:          idToken.Claims.(*IDTokenClaims).Email,
+			IsPrivateEmail: idToken.Claims.(*IDTokenClaims).IsPrivateEmail,
 		}
 	}
 
diff --git a/providers/apple/session_test.go b/providers/apple/session_test.go
index 845c17541..7d0aa437e 100644
--- a/providers/apple/session_test.go
+++ b/providers/apple/session_test.go
@@ -35,7 +35,7 @@ func Test_ToJSON(t *testing.T) {
 	s := &Session{}
 
 	data := s.Marshal()
-	a.Equal(data, `{"AuthURL":"","AccessToken":"","RefreshToken":"","ExpiresAt":"0001-01-01T00:00:00Z","sub":""}`)
+	a.Equal(data, `{"AuthURL":"","AccessToken":"","RefreshToken":"","ExpiresAt":"0001-01-01T00:00:00Z","sub":"","email":"","is_private_email":false}`)
 }
 
 func Test_String(t *testing.T) {