# Onboarding Entities

The CORTEX proxy acts as an Identity Provider (IdP) toward the
Service Providers (SPs) it serves, and as a SP toward the IdPs it brokers to. Onboarding a new entity means registering its metadata
on the correct side of the proxy. This page explains where that metadata lives,
how to supply it, and the steps to add a new SP or IdP.

## The two directions of trust

Trust runs in two directions, and each has its own set of values.

| Direction | Proxy role | Trusts | Configured by |
| --------- | ---------- | ------ | ------------- |
| Toward service providers | Identity provider (frontend) | The SPs that rely on the proxy for login | `Proxy.trusted-sps`, `Proxy.mdq` (the registry is trusted automatically) |
| Toward identity providers | Service provider (backend) | The IdPs the proxy authenticates users against | `Proxy.upstream-idps`, `Proxy.idp-metadata-configmap` |
| Home realm discovery | Discovery service (WAYF) | The IdPs a user may pick from | `Discovery.metadata-providers` |

None of these carry site-specific defaults. The chart ships with empty lists, and
each deployment supplies its own partners through a values file.

The proxy publishes its own metadata at two well known URLs, which you hand to
partners so they can trust the proxy in return:

| Proxy endpoint | URL | Give it to |
| -------------- | --- | ---------- |
| Proxy IdP metadata | `https://<Proxy.hostname>/idp` | A service provider you onboard |
| Proxy SP metadata | `https://<Proxy.hostname>/sp` | An identity provider you onboard |

## Onboarding a Service Provider

A service provider is any application that logs its users in through the proxy.
The registry is one such service provider, and the chart registers it for you
from `Registry.hostname`, so you never list it by hand.

To add another service provider:

1. Obtain the service provider's SAML metadata URL, for example
   `https://sp.example.org/Shibboleth.sso/Metadata`.
2. Add it to `Proxy.trusted-sps`:

   ```yaml
   Proxy:
     trusted-sps:
       - https://sp.example.org/Shibboleth.sso/Metadata
   ```

3. Give the service provider operator the proxy identity provider metadata URL,
   `https://<Proxy.hostname>/idp`, so their service trusts the proxy in return.
   Trust has to exist on both ends before login works.
4. Apply the change (see [Applying changes](#applying-changes)).

:::{tip}
If your federation publishes service provider metadata through a metadata query
(MDQ) service, such as InCommon, you can let the proxy resolve any member service
provider on demand instead of listing them one by one. Add the MDQ server under
`Proxy.mdq`, giving its URL and the path to its signing certificate (mounted from
`config/proxy/satosa-root/`):

```yaml
Proxy:
  mdq:
    - url: https://mdq.incommon.org/
      cert: /etc/satosa/inc-md-cert-mdq.crt
```
:::

## Onboarding an Identity Provider

An Identity Provider is a login source, such as a campus login service or a
social login gateway, that authenticates a user before the proxy asserts their
identity to a service provider. There are two ways to register one, and the right
choice depends on whether the identity provider publishes reachable, trustworthy
metadata over HTTPS.

### By URL

Use this when the identity provider serves its metadata at an HTTPS URL with a
certificate the proxy can verify. List the URL under `Proxy.upstream-idps.remote`,
and add it to the discovery providers so users can select it:

```yaml
Proxy:
  upstream-idps:
    remote:
      - https://login.example.org/idp/shibboleth
Discovery:
  metadata-providers:
    - url: https://login.example.org/idp/shibboleth
      backing-file: example-idp.xml
```

:::{warning}
The proxy fetches every remote URL when it starts and refuses to boot if one is
unreachable or presents a certificate it cannot verify. A single unreachable
partner takes the whole proxy down.
:::

### By file

Use this when the identity provider's metadata is not reachable over HTTPS, or its
certificate does not verify. You keep the metadata as a file and mount it into the
proxy through a ConfigMap you manage. This is the recommended default.

1. Save the identity provider's metadata XML outside the chart. This repository
   uses `local/idp-metadata/`, which is git ignored:

   ```bash
   curl -sk https://login.example.org/idp/shibboleth \
     -o local/idp-metadata/example-idp.xml
   ```

2. Create or refresh the ConfigMap from that directory:

   ```bash
   kubectl -n <NAMESPACE> create configmap cortex-idp-metadata \
     --from-file=local/idp-metadata/ \
     --dry-run=client -o yaml | kubectl apply -f -
   ```

3. Reference the ConfigMap and the mounted file paths in your values. The
   filenames you supply become the filenames under `/etc/satosa/metadata/idp/`,
   so the paths must match:

   ```yaml
   Proxy:
     idp-metadata-configmap: cortex-idp-metadata
     upstream-idps:
       local:
         - /etc/satosa/metadata/idp/example-idp.xml
   ```

4. Add the same provider to the discovery service so it appears in the picker
   (see below).

### Making it selectable in discovery

The discovery service presents the list of identity providers a user can choose
from. Add each provider to `Discovery.metadata-providers`. Every entry needs a
`url` and a `backing-file`, and may set `max-refresh` (seconds, default 3600) and
an `include` list that filters the entry down to the specific entities you trust:

```yaml
Discovery:
  metadata-providers:
    - url: https://md.example.org/social-providers.xml
      backing-file: social-providers.xml
      include:
        - https://example.org/gateway
    - url: https://mdq.incommon.org/entities/idps/all
      backing-file: InCommon-metadata-idp-only.xml
```

:::{tip}
An identity provider generally needs to be known on both sides to be usable end
to end: in `Discovery.metadata-providers` so a user can select it, and in
`Proxy.upstream-idps` so the proxy can complete authentication against it.
:::

## Per service provider overrides

Some service providers need a non default subject identifier format. Map the
service provider entity ID to the format it requires under
`Proxy.subject-type-overrides`:

```yaml
Proxy:
  subject-type-overrides:
    https://sp.example.org/shibboleth: urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified
```

## Applying changes

Changes to the values above take effect on a Helm upgrade:

```bash
helm upgrade <Release.Name> cortex/cortex -f my-values.yaml -n <NAMESPACE>
```

When you only change the contents of the identity provider metadata ConfigMap,
without changing any values, restart the proxy so it picks up the new files:

```bash
kubectl -n <NAMESPACE> rollout restart deploy/proxy
```

:::{warning}
Create the `cortex-idp-metadata` ConfigMap before the first install. Without it
the proxy pod waits in `Init` with a `configmap not found` mount error. If that
happens, create the ConfigMap and the pod proceeds on its next retry.
:::
