Is it possible to use Tik Identity Broker without Dashboard?

Hi, I am planning to use TyK and TIB, as identity handler, following the flow of the following figure obtained from the TIB documentation.

However, reviewing the documentation it states that starting from Tyk v3.0 TIB has been added as a built-in feature of the Tyk Dashboard. Since I have seen that the TIB project is still maintained as Open Source, as is TyK, I would like to confirm what:

  1. Is it possible to use TIB as identity handler without using the TyK dashboard?
  2. Is it possible to use the latest docker hub Identity Broker Tag for this purpose?
  3. Is there a helm chart for TIB that can be used for this purpose?

Thanks in advance,

Santiago.

@sfigueroa Apologies for the delay in getting to this.Welcome to the community

Yes it is still possible. In fact it is the only way to achieve SSO for now on the Enterprise Portal since it’s yet to be embedded into the portal like the dashboard

Yes it is very possible. The docker image matches the latest version from the source

I don’t think there is since I couldn’t find any on Artifact Hub. Even the tyk-stack and tyk-oss charts don’t have it.

Asking internally. Will come back with an update soon

Thanks for the answer @Olu. I would like to configure TIB to connect to an external IdP using SAML2.

Context:

  1. Version 1.5.1 of TIB docker has been deployed like this:
docker run --name tyk-identity-broker -p 3100:3010 -e TYK_IB_SESSION_SECRET=foo -e TYK_LOGLEVEL=debug -v $(pwd)/tib.conf:/opt/tyk-identity-broker/tib.conf -v $(pwd)/profiles.json:/opt/tyk-identity-broker/profiles.json tykio/tyk-identity-broker:v1.5.1
  1. The following tib.conf and profiles.json have been loaded:

tib.conf:

[
    {
        "ID": "saml-sso-login",
        "OrgID": "1",
        "ActionType": "GenerateOAuthTokenForClient",
        "Type": "passthrough",
        "ProviderName": "SAMLProvider",
        "ProviderConfig":
        {
            "ForceAuthentication": false,
            "IDPMetaDataURL": "https://caspre.mydomain/cas/idp/metadata",
            "SAMLBaseURL": "http://10.63.28.51:3100/"
        },
        "IdentityHandlerConfig":
        {
            "TokenAuth":
            {
                "BaseAPIID": "1"
            }
        }
    }
]

profiles.json:

{
    "Secret": "foo",
    "HttpServerOptions":
    {
        "UseSSL": false,
        "CertFile": "",
        "KeyFile": ""
    },
    "SSLInsecureSkipVerify": true,
    "BackEnd":
    {
        "Name": "redis",
        "IdentityBackendSettings":
        {
            "Hosts" :
            {
                "10.63.28.51": "6379"
            },
            "Password": "",
            "Database": 0,
            "EnableCluster": false,
            "MaxIdle": 1000,
            "MaxActive": 2000
        }
    },
    "TykAPISettings":
    {
        "GatewayConfig":
        {
            "Endpoint": "http://10.63.28.51",
            "Port": "8080",
            "AdminSecret": "352d20ee67be67f6340b4c0605b044b7"
        }
    }
}
  1. TIB returns the following log:

  1. The TIB API returns on the following request curl http://localhost:3100/api/profiles -H "Authorization: foo":
{"Status":"ok","ID":"","Data":[{"ID":"saml-sso-login","Name":"","OrgID":"1","ActionType":"GenerateOAuthTokenForClient","MatchedPolicyID":"","Type":"passthrough","ProviderName":"SAMLProvider","CustomEmailField":"","CustomUserIDField":"","ProviderConfig":{"ForceAuthentication":false,"IDPMetaDataURL":"https://caspre.unav.es/cas/idp/metadata","SAMLBaseURL":"http://10.63.28.51:3100/"},"IdentityHandlerConfig":{"TokenAuth":{"BaseAPIID":"1"}},"ProviderConstraints":{"Domain":"","Group":""},"ReturnURL":"","DefaultUserGroupID":"","CustomUserGroupField":"","UserGroupMapping":null,"UserGroupSeparator":"","SSOOnlyForRegisteredUsers":false}]}

Questions:

  1. Since the /health endpoint does not respond, must something be missing in the configuration?
  2. The external IdP is reached, but I get this error. Am I missing some configuration?
time="Aug 05 09:56:57" level=debug msg="--> Looking up profile ID: saml-sso-login" prefix="AUTH HANDLERS"
time="Aug 05 09:56:57" level=debug msg="Initializing Identity Handler with config: {ID:saml-sso-login Name: OrgID:1 ActionType:GenerateOAuthTokenForClient MatchedPolicyID: Type:passthrough ProviderName:SAMLProvider CustomEmailField: CustomUserIDField: ProviderConfig:map[ForceAuthentication:false IDPMetaDataURL:https://caspre.mydomain.domain/cas/idp/metadata SAMLBaseURL:http://10.63.28.51:3100/] IdentityHandlerConfig:map[TokenAuth:map[BaseAPIID:1]] ProviderConstraints:{Domain: Group:} ReturnURL: DefaultUserGroupID: CustomUserGroupField: UserGroupMapping:map[] UserGroupSeparator: SSOOnlyForRegisteredUsers:false}"
time="Aug 05 09:56:57" level=warning msg="No expiry found - defaulting to 3600 seconds" prefix="TYK ID HANDLER"
time="Aug 05 09:56:57" level=debug msg="Initializing Provider"
time="Aug 05 09:56:57" level=debug msg="Initializing SAML profile with config: {IDPMetadataURL:https://caspre.mydomain.domain/cas/idp/metadata CertLocation: SAMLBaseURL:http://10.63.28.51:3100/ ForceAuthentication:false SAMLBinding: SAMLEmailClaim: SAMLForenameClaim: SAMLSurnameClaim: FailureRedirect: EntityId:}" prefix="SAML AUTH"
time="Aug 05 09:56:57" level=debug msg="Initialising middleware SAML" prefix="SAML AUTH"
time="Aug 05 09:56:57" level=error msg="Could not read cert file: open : no such file or directory" prefix="CERT FILE LOADER"
time="2024-08-05T09:56:57Z" level=warning msg="Can't retrieve certificate:open : no such file or directory" prefix=cert_storage
time="Aug 05 09:56:57" level=debug msg="Certificate Loaded" prefix="SAML AUTH"
time="Aug 05 09:56:57" level=debug msg="KeyPair: <nil>"
time="Aug 05 09:56:57" level=debug msg="Parsing IDP metadata URL successful" prefix="SAML AUTH"
time="Aug 05 09:56:57" level=debug msg="IDPmetadataURL is: https://caspre.mydomain.domain/cas/idp/metadata" prefix="SAML AUTH"
time="Aug 05 09:56:57" level=debug msg="Parsing SAML Base URL successful, Root URL: http://10.63.28.51:3100/" prefix="SAML AUTH"
time="Aug 05 09:56:57" level=debug msg="IDP Metadata retrieved successfully" prefix="SAML AUTH"
time="Aug 05 09:56:57" level=debug msg="IDP Metadata: &{XMLName:{Space: Local:} EntityID:https://caspre.mydomain.domain/cas/idp ID: ValidUntil:0001-01-01 00:00:00 +0000 UTC CacheDuration:0s Signature:<nil> RoleDescriptors:[] IDPSSODescriptors:[{XMLName:{Space:urn:oasis:names:tc:SAML:2.0:metadata Local:IDPSSODescriptor} SSODescriptor:{RoleDescriptor:{ID: ValidUntil:<nil> CacheDuration:0s ProtocolSupportEnumeration:urn:oasis:names:tc:SAML:2.0:protocol urn:oasis:names:tc:SAML:1.1:protocol urn:mace:shibboleth:1.0 ErrorURL:https://caspre.mydomain.domain/cas/idp/error Signature:<nil> KeyDescriptors:[{Use:signing KeyInfo:{XMLName:{Space:http://www.w3.org/2000/09/xmldsig# Local:KeyInfo} X509Data:{XMLName:{Space:http://www.w3.org/2000/09/xmldsig# Local:X509Data} X509Certificates:[{XMLName:{Space:http://www.w3.org/2000/09/xmldsig# Local:X509Certificate} Data:MIIDKzCCAhOgAwIBAgIUMt5gkWmFNZInR1jXcG9ar7XfC6cwDQYJKoZIhvcNAQEF
7gfZM5aYv+ots1i+60pBSHZFbBfpHLNUgiUS0B/YGuRJbs0lUVp2USVtWI4Ffmol
Fw00NTA1MjIwOTMxMTJaMBsxGTAXBgNVBAMTEGxvZ2lucHJlLnVuYXYuZXMwggEi
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6jYWCNG7d9BAfmFTo7Xu2YvlF
idzlus13TSothlpFJYSNHat6PQHqocWX+RTpeuRqwQC7CLrCThj2xyIsUL0j7bFm
y+fuhUYhD6SCivrBrVdk0X9oqxkrKhn8R9BL8QwMFzDuT4nRCvQ62FdOgZCx82W4
1AG+ncCSokbUls9NuIUdxL8iDa0ep0Lm3nsGhb5acE32fXv6tytS4IcZbd3X4Rkm
AAGjZzBlMEQGA1UdEQQ9MDuCEGxvZ2lucHJlLnVuYXYuZXOGJ2h0dHBzOi8vbG9n
8G2rer6F6jYVNIg239VaTBWbUK80qyd1FNeCfG9leYu6EvbQYNcYIrJK7HVDAgMB
AAGjZzBlMEQGA1UdEQQ9MDuCEGxvZ2lucHJlLnVuYXYuZXOGJ2h0dHBzOi8vbG9n
aW5wcmUudW5hdi5lcy9pZHAvc2hpYmJvbGV0aDAdBgNVHQ4EFgQUZmXxwgugdeFr
AvAVO6jlSLJhUH8wDQYJKoZIhvcNAQEFBQADggEBACu8AuhCtN+GObODJhdQNMia
ABnLTi59asp5s0yiJlXfbu6Rz5vHVLollunokdW2ixiGwhmFuOmi1VSuMKg8hOB8
7gfZM5aYv+ots1i+60pBSHZFbBfpHLNUgiUS0B/YGuRJbs0lUVp2USVtWI4Ffmol
0pR8PBWTdaXyhkQ7ttlD35y4HhZOnyClSGxzrngyvCuvBuuytaqZs8TJ+2iIW/Yq
UdA1s2Nw+dIulfdWMrylhDFu7BfZG3FI1k0Q78NNlSPZTpTB/WvUQ72sc+bFufKD
CBUL5SFMOzr7mwqkCaQMUolJN+0E90MMstIaorEvjS/UeHsRbTVD/ma/GuVgavI=
}]}} EncryptionMethods:[]} {Use:encryption KeyInfo:{XMLName:{Space:http://www.w3.org/2000/09/xmldsig# Local:KeyInfo} X509Data:{XMLName:{Space:http://www.w3.org/2000/09/xmldsig# Local:X509Data} X509Certificates:[{XMLName:{Space:http://www.w3.org/2000/09/xmldsig# Local:X509Certificate} Data:MIIDKzCCAhOgAwIBAgIUMt5gkWmFNZInR1jXcG9ar7XfC6cwDQYJKoZIhvcNAQEF
7gfZM5aYv+ots1i+60pBSHZFbBfpHLNUgiUS0B/YGuRJbs0lUVp2USVtWI4Ffmol
Fw00NTA1MjIwOTMxMTJaMBsxGTAXBgNVBAMTEGxvZ2lucHJlLnVuYXYuZXMwggEi
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6jYWCNG7d9BAfmFTo7Xu2YvlF
idzlus13TSothlpFJYSNHat6PQHqocWX+RTpeuRqwQC7CLrCThj2xyIsUL0j7bFm
y+fuhUYhD6SCivrBrVdk0X9oqxkrKhn8R9BL8QwMFzDuT4nRCvQ62FdOgZCx82W4
1AG+ncCSokbUls9NuIUdxL8iDa0ep0Lm3nsGhb5acE32fXv6tytS4IcZbd3X4Rkm
AAGjZzBlMEQGA1UdEQQ9MDuCEGxvZ2lucHJlLnVuYXYuZXOGJ2h0dHBzOi8vbG9n
8G2rer6F6jYVNIg239VaTBWbUK80qyd1FNeCfG9leYu6EvbQYNcYIrJK7HVDAgMB
AAGjZzBlMEQGA1UdEQQ9MDuCEGxvZ2lucHJlLnVuYXYuZXOGJ2h0dHBzOi8vbG9n
aW5wcmUudW5hdi5lcy9pZHAvc2hpYmJvbGV0aDAdBgNVHQ4EFgQUZmXxwgugdeFr
AvAVO6jlSLJhUH8wDQYJKoZIhvcNAQEFBQADggEBACu8AuhCtN+GObODJhdQNMia
ABnLTi59asp5s0yiJlXfbu6Rz5vHVLollunokdW2ixiGwhmFuOmi1VSuMKg8hOB8
7gfZM5aYv+ots1i+60pBSHZFbBfpHLNUgiUS0B/YGuRJbs0lUVp2USVtWI4Ffmol
0pR8PBWTdaXyhkQ7ttlD35y4HhZOnyClSGxzrngyvCuvBuuytaqZs8TJ+2iIW/Yq
UdA1s2Nw+dIulfdWMrylhDFu7BfZG3FI1k0Q78NNlSPZTpTB/WvUQ72sc+bFufKD
CBUL5SFMOzr7mwqkCaQMUolJN+0E90MMstIaorEvjS/UeHsRbTVD/ma/GuVgavI=}]}} EncryptionMethods:[]}] Organization:<nil> ContactPeople:[]} ArtifactResolutionServices:[] SingleLogoutServices:[{Binding:urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST Location:https://caspre.mydomain.domain/cas/idp/profile/SAML2/POST/SLO ResponseLocation:} {Binding:urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect Location:https://caspre.mydomain.domain/cas/idp/profile/SAML2/Redirect/SLO ResponseLocation:}] ManageNameIDServices:[] NameIDFormats:[urn:mace:shibboleth:1.0:nameIdentifier urn:oasis:names:tc:SAML:2.0:nameid-format:transient]} WantAuthnRequestsSigned:<nil> SingleSignOnServices:[{Binding:urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST Location:https://caspre.mydomain.domain/cas/idp/profile/SAML2/POST/SSO ResponseLocation:} {Binding:urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST-SimpleSign Location: ResponseLocation:} {Binding:urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect Location:https://caspre.mydomain.domain/cas/idp/profile/SAML2/Redirect/SSO ResponseLocation:} {Binding:urn:oasis:names:tc:SAML:2.0:bindings:SOAP Location:https://caspre.mydomain.domain/cas/idp/profile/SAML2/SOAP/ECP ResponseLocation:}] ArtifactResolutionServices:[] NameIDMappingServices:[] AssertionIDRequestServices:[] AttributeProfiles:[] Attributes:[]}] SPSSODescriptors:[] AuthnAuthorityDescriptors:[] AttributeAuthorityDescriptors:[] PDPDescriptors:[] AffiliationDescriptor:<nil> Organization:<nil> ContactPerson:<nil> AdditionalMetadataLocations:[]}" prefix="SAML AUTH"
time="Aug 05 09:56:57" level=debug msg="Root URL: http://10.63.28.51:3100/" prefix="SAML AUTH"
time="Aug 05 09:56:57" level=error msg="profile certificate was not loaded" prefix="SAML AUTH"
time="Aug 05 09:56:57" level=debug msg="HandleMetadata Called..." prefix="SAML AUTH"
2024/08/05 09:56:57 http: panic serving 10.63.28.51:52934: runtime error: invalid memory address or nil pointer dereference
goroutine 37 [running]:
net/http.(*conn).serve.func1()
        /usr/local/go/src/net/http/server.go:1868 +0xb9
panic({0xd8f200?, 0x1624220?})
        /usr/local/go/src/runtime/panic.go:920 +0x270
github.com/TykTechnologies/tyk-identity-broker/providers.(*SAMLProvider).HandleMetadata(0xc0001383c0, {0x102e5d8, 0xc000190000}, 0x4?)
        /go/src/github.com/TykTechnologies/tyk-identity-broker/providers/saml.go:343 +0x78
main.HandleMetadata({0x102e5d8, 0xc000190000}, 0xc0003a01e0?)
        /go/src/github.com/TykTechnologies/tyk-identity-broker/http_handlers.go:80 +0x166
net/http.HandlerFunc.ServeHTTP(0xc00018a400?, {0x102e5d8?, 0xc000190000?}, 0x7ff0935aea20?)
        /usr/local/go/src/net/http/server.go:2136 +0x29
github.com/gorilla/mux.(*Router).ServeHTTP(0xc0001063c0, {0x102e5d8, 0xc000190000}, 0xc00018a100)
        /go/pkg/mod/github.com/gorilla/[email protected]/mux.go:210 +0x1c5
net/http.serverHandler.ServeHTTP({0xc0003a0090?}, {0x102e5d8?, 0xc000190000?}, 0x6?)
        /usr/local/go/src/net/http/server.go:2938 +0x8e
net/http.(*conn).serve(0xc000186000, {0x102fb18, 0xc0002cdaa0})
        /usr/local/go/src/net/http/server.go:2009 +0x5f4
created by net/http.(*Server).Serve in goroutine 1
        /usr/local/go/src/net/http/server.go:3086 +0x5cb
  1. I have also configured Redis to get this property, still without success.
For Identity Handlers that provide token-based access, it is possible to enforce a "One token per provider, per user" policy, which keeps a cache of tokens assigned to identities in Redis, this is so that the broker can be scaled and share the cache across instances.

Hi @Olu.

The error has been solved thanks to the generation of certificates (self-signed in this case). The certificate has been enabled in the profiles.json in this way:

...
"ProviderConfig": 
        {
            "CertLocation": "/opt/tyk-identity-broker/cert.pem",
            "ForceAuthentication": false,
            "IDPMetaDataURL": "https://mydomain.es/cas/idp/metadata",
            "SAMLBaseURL": "http://10.63.28.51:3100/"
        },
...

One clue is that cert.pem combines the certificate and the private key as indicated in the documentation:

CertLocation: An X.509 certificate and the private key for signing your requests to the IDP, this should be one single file with the cert and key concatenated.

Now I am focusing on steps 6 and 7. Do you know if these steps would be performed “automatically” or would I need to force the call between both containers?

I thought the interaction might already be set thanks to the information added in the TIB configuration file.

    "TykAPISettings": 
    {
        "GatewayConfig": 
        {
            "Endpoint": "http://10.63.28.51",
            "Port": "8080",
            "AdminSecret": "xxxxxx"
        }
    }

Thanks,

Santiago.

Sorry for the delayed response. I was on holiday.

I believe it would be automatic from TIB. The user interactions are 01, 03 and 08

Hi,

I’m trying this implementation of both the api gateway and the identity broker without the dashboard. Everything is working when I create the oauth client like this:

curl -X POST -H "x-tyk-authorization: foo" -H "Content-Type: application/json" -d '
    {
        "client_id": "C3",
        "client_secret": "foo",
        "redirect_uri": "http://redirect.uri",
        "grant_types": ["authorization_code", "refresh_token"],
        "response_types": ["code"],
        "name": "C3"
    }' tyk-helm-chart-gateway:8080/tyk/oauth/clients/create

And this is the profiles.json:

[
      {
        "ID": "saml-sso-login",
        "OrgID": "1",
        "ActionType": "GenerateOAuthTokenForClient",
        "Type": "passthrough",
        "ProviderName": "SAMLProvider",
        "ProviderConfig": {
            "CertLocation": "/opt/tyk-identity-broker/tyk-identity-broker-combined.pem",
            "ForceAuthentication": false,
            "IDPMetaDataURL": "metadataURL",
            "SAMLBaseURL": "baseURL",
            "SAMLEmailClaim": "urn:oid:0.9.2342.19200300.100.1.3",
            "SAMLForenameClaim": "urn:oid:2.5.4.42",
            "SAMLSurnameClaim": "urn:oid:2.5.4.4"
        },
        "IdentityHandlerConfig": 
        {
          "OAuth": 
          {
              "APIListenPath": "api",
              "RedirectURI": "redirectUri",
              "ResponseType": "code",
              "ClientId": "C3",
              "Secret": "foo",
              "BaseAPIID": "A3",
              "NoRedirect": false
          }
        }
      }
    ]

The whole process is working, this is the log I get in the TIB:

time="Nov 05 14:51:38" level=debug msg="Calling: http://tyk-helm-chart-gateway:8080/api/tyk/oauth/authorize-client/" prefix="TYK_API"

time="Nov 05 14:51:38" level=debug msg="API Response: {"code":"N_iBL1456tmp1blHr9yYSA","redirect_to":"http://redirect.uri?code=N_iBL1456tmp1blHr9yYSA"}

However, I need to be able to get the user that has been identified in the IDP, so I’m trying to change the response type. When I just change it to token, in both “ResponseType” fields (profiles.json and oauth client) I get this error in the tyk api gateway:

time="Nov 05 15:12:21" level=error msg="[OAuth] OAuth response marked as error: &{0 403 The authorization server does not support obtaining a token using this method. 403 map[error:unsupported_response_type error_description:The authorization server does not support obtaining a token using this method.] map[Cache-Control:[no-store]] true <nil> false 0xc000b55d10}"

Is there a way of getting all the info the IDP returns or at least the username which has been used for the authorization?