Sign in with DocuWare

Users open DocuWare Ivy and are already signed in, with the DocuWare account they use every day. There is no second login and no separate password.

This is an alternative to Connect Microsoft Entra ID. Pick one: either DocuWare signs users in, or Entra ID does.

Nothing about the installation changes: the same host name, the same IIS rule, the same containers. Two addresses, and they sign in differently:

Address

Who signs in

https://<public-host>/ivy/docuware/project-ivy/

DocuWare. This is the address you give your users.

https://<public-host>/ivy/system/

The Engine Cockpit keeps its own administrator login, so you can still reach it if sign-in is misconfigured.

Before you start

1. The public host name must be the licensed one.

DocuWare Ivy is licensed for one public address. Users must reach Ivy under exactly that name — the same one in BaseUrl in config/ivy.yaml. A different name is answered with a bare 400, with no explanation in the browser.

2. Register an application in DocuWare.

Sign in to DocuWare as an organisation administrator and open Configurations ‣ App Registration. Add an application:

Field

Value

Application type

Web application

Grant type

Authorization Code

Redirect URLs

https://<public-host>/ivy/docuware/oauth2/callback
https://<public-host>/ivy/docuware/signout-oidc

Allowed resources

Platform API

Use refresh token

leave off

Save. DocuWare shows the Application (Client) ID and lets you create a client secret. Copy the secret straight away — it is shown once.

3. Read three values out of DocuWare.

Open this address in a browser, signed in or not:

https://<docuware-host>/DocuWare/Platform/Home/IdentityServiceInfo

It answers with IdentityServiceUrl — the address of your Identity Service, for example https://<docuware-host>/DocuWare/Identity. Open that address with /.well-known/openid-configuration on the end, and copy two more values out of the answer, exactly as they are written there:

Value

Goes into .env as

IdentityServiceUrl

IVY_SSO_AUTHORITY

issuer

IVY_SSO_ISSUER

jwks_uri

IVY_SSO_JWKS_URI

Configure it

One file: .env, in the folder you installed from. Seven lines.

IVY_SSO_MODE=sso
IVY_SSO_PROXY_IMAGE=docuwarepublic.azurecr.io/ivy/sso-proxy:0.1.0
IVY_SSO_AUTHORITY=<the IdentityServiceUrl you copied>
IVY_SSO_CLIENT_ID=<the Application (Client) ID>
IVY_SSO_CLIENT_SECRET=<the client secret from App Registration>
IVY_SSO_ISSUER=<the issuer value>
IVY_SSO_JWKS_URI=<the jwks_uri value>

The proxy is a second image, published alongside the engine. Pin the version rather than using latest, for the same reason as the engine.

IVY_SSO_MODE is the whole switch. It turns sign-in on for the proxy and for the engine at the same time, so the two can never end up on opposite sides of it. Set it to entra and both are off again.

Nothing else is edited. docker-compose.yml, the compose overlay and the files under config/ read their values from here.

Note

Note

If the secret contains a $, write it twice: $$. Everything after a single $ is otherwise dropped, and the proxy then fails to start with a message about a missing secret.

Then start the stack with the sign-in overlay:

docker compose -f docker-compose.yml -f compose.sso.yml up -d

compose.sso.yml and the files under config/ it needs are in the installation bundle, but the install guide copies only the four files a plain installation needs. Copy the rest across now, from the same C:\ivy-install folder:

Listing 14 On your Windows machine
ssh <your-user>@<linux-host> "mkdir -p <path-from-pwd>/config/proxy"

cd C:\ivy-install
scp compose.sso.yml                     <your-user>@<linux-host>:<path-from-pwd>/
scp config\context.xml                  <your-user>@<linux-host>:<path-from-pwd>/config/
scp config\log4j2.xml                   <your-user>@<linux-host>:<path-from-pwd>/config/
scp config\mode.sso.env                 <your-user>@<linux-host>:<path-from-pwd>/config/
scp config\mode.entra.env               <your-user>@<linux-host>:<path-from-pwd>/config/
scp config\proxy\appsettings.sso.json   <your-user>@<linux-host>:<path-from-pwd>/config/proxy/
scp config\proxy\appsettings.entra.json <your-user>@<linux-host>:<path-from-pwd>/config/proxy/

Both mode.* files and both appsettings.* files, not just the sso ones: IVY_SSO_MODE chooses between them at start, so the one you are not using still has to be there.

If DocuWare's certificate is not trusted

Skip this unless you need it. Giving DocuWare a certificate the Linux host already trusts is the right answer and makes the whole section unnecessary. This is for a pilot where that is not available yet, typically a self-signed certificate or an incomplete chain.

It has to be done twice, because the two halves of sign-in trust separately: the proxy reads the discovery document with .NET and uses the system store, the engine reads the signing keys with Java and uses a Java truststore. Neither of them reports a certificate problem in a way that says so - see If something is wrong for the two messages.

Everything below runs on the Linux host, in the folder you installed from. No tools have to be installed: both images already carry what is needed.

1. Save the certificate DocuWare presents.

openssl s_client -connect <docuware-host>:443 -servername <docuware-host> \
  < /dev/null 2>/dev/null | openssl x509 -out config/docuware.crt

2. Build three files: a truststore for the engine, the engine's JVM options with two lines added that point at it, and a CA bundle for the proxy. Each command runs the image it is building for, so each file starts from what that component itself ships and nothing is guessed.

Put in your own two image names: the engine is IVY_IMAGE and IVY_IMAGE_TAG from .env joined with a colon, the proxy is IVY_SSO_PROXY_IMAGE. Do not source that file to read them - it is read by Compose, not by the shell.

docker run --rm --user root --entrypoint sh \
  -v "$PWD/config:/certs" <engine image> -c \
  'cp /opt/java/openjdk/lib/security/cacerts /certs/truststore.jks && \
   keytool -importcert -noprompt -alias docuware -file /certs/docuware.crt \
     -keystore /certs/truststore.jks -storepass changeit && \
   cp /ivy/configuration/jvm.options /certs/jvm.options && \
   printf "\n-Djavax.net.ssl.trustStore=/ivy/configuration/truststore.jks\n-Djavax.net.ssl.trustStorePassword=changeit\n" \
     >> /certs/jvm.options'

docker run --rm --user root --entrypoint sh \
  -v "$PWD/config:/certs" <proxy image> -c \
  'cat /etc/ssl/certs/ca-certificates.crt /certs/docuware.crt > /certs/ca-bundle.pem'

3. Switch them on. Four lines that ship commented out, nothing to write yourself:

In

Uncomment

docker-compose.yml

the truststore.jks and jvm.options volumes, under the licence

compose.sso.yml

SSL_CERT_FILE and the ca-bundle.pem volume

changeit is the standard password of a Java truststore and is not a secret: the file holds public certificates and the password only guards against accidental edits.

Then restart, and carry on with Add the users:

docker compose -f docker-compose.yml -f compose.sso.yml up -d
Note

Note

Rebuild the files when DocuWare's certificate is replaced. Nothing warns you: the old one keeps working until it expires, and then sign-in stops.

Rebuild jvm.options on an engine upgrade too. It is a copy of the engine's own file, so a mounted one pins the old version's heap and garbage collector settings.

Add the users

Signing in is not the same as having an account. DocuWare says who the user is; Ivy still needs a user of its own with the same name, or the portal shows its own login page even though sign-in worked.

Two ways to get them there:

  • Import them, as described in Connect Microsoft Entra ID. This is the right answer for more than a handful of users, because it also keeps them up to date.

  • Create them by hand in the Engine Cockpit, under the docuware security system. The user name must match the DocuWare user name exactly.

Check it works

Open https://<public-host>/ivy/docuware/project-ivy/ in a browser where you are already signed in to DocuWare. The portal should open directly, with no login page and with your own name in the top right.

Then open https://<public-host>/ivy/system/. It should still ask for the Engine Cockpit administrator — that page is deliberately not behind DocuWare sign-in.

Signing out

The portal's own logout does not sign the user out. Tell your users before they rely on it.

Identity comes from the token the sign-in proxy forwards, and the engine checks that token on every single request. So the portal's logout ends the Ivy session, the browser is sent back, the same token arrives again, and a new session is created for the same user. They stay on the page, still signed in.

The address that does sign a user out:

https://<public-host>/ivy/docuware/logout

It clears the proxy's session cookie and then sends the browser to DocuWare's Identity Service to end the session there as well. The address it returns to is the signout-oidc one from Before you start, so register both redirect URLs and not only the first.

The portal can hide its logout entry, which is worth doing if you would rather users did not find a control that appears to do nothing. It is a Portal variable, set per application:

Variables:
  Portal:
    UserMenu:
      HideLogoutMenu: "true"

After changing it, confirm the sign-out address works end to end in a browser: open it, then open the portal again. You should be asked for your DocuWare credentials rather than let straight back in.

If something is wrong

The engine writes its log to logs/ivy.log in the installation folder. Almost every answer is in there.

Note
The log folder is empty and stays empty

The engine could not write to it. Stop the stack, then:

sudo chown 1000:0 logs && chmod g+rwX logs

and start it again.

Note
The browser shows a bare 400

The address you used is not the one in the licence. logs/ivy.log names both:

The requested url 'https://.../ivy/...' is not accepted by the
licenced public urls '...'

Use the licensed name, or ask DocuWare support to reissue the licence for the name you want to use.

Note
Sign-in works but the portal shows its own login page

There is no Ivy user with that name. See Add the users.

Note
Every request ends in 401

logs/ivy.log gives the reason on the line after the one naming DocuWareJwtValve:

grep -A1 DocuWareJwtValve logs/ivy.log

An issuer that does not match is the usual cause — compare IVY_SSO_ISSUER in .env with the issuer field of the discovery document again, including upper and lower case.

Note
The proxy restarts, or 401 although sign-in worked

A certificate the host does not trust — a self-signed one in a pilot, or an incomplete chain — stops this in two places, and neither message leads with the word certificate.

The proxy cannot read the discovery document, so it never starts:

IDX20804: Unable to retrieve document from
'.../DocuWare/Identity/.well-known/openid-configuration'
The remote certificate is invalid because of errors in the
certificate chain: UntrustedRoot

The valve cannot read the signing keys, so every request is 401 even though the user signed in and a token arrived:

JWKSetRetrievalException: Couldn't retrieve JWK set from URL:
(certificate_unknown) PKIX path building failed

Both need a certificate the machine trusts, and the two components trust separately: the proxy uses the system store, the engine uses Java's. Giving DocuWare a certificate its own clients already accept fixes both. If you cannot yet, see If DocuWare's certificate is not trusted.

Note
502 after both machines were restarted

docker logs on the proxy names the real error, and it is not the certificate one above - that is IDX20804, this is IDX20807:

IDX20807: Unable to retrieve document from
'.../DocuWare/Identity/.well-known/openid-configuration'

The proxy asked DocuWare for its discovery document while DocuWare was still starting, and got an error back instead of the document. Compose waits for the engine before starting the proxy, but it has no way to wait for DocuWare, which is on the other machine. The proxy answers 500 and IIS reports that to the browser as 502.

Check that DocuWare is up - it should answer 200 - then restart the proxy:

curl -s -o /dev/null -w '%{http_code}\n' \
  https://<docuware-host>/DocuWare/Identity/.well-known/openid-configuration

docker compose -f docker-compose.yml -f compose.sso.yml restart sso-proxy

Ask for the document, not the headers: that endpoint answers 405 to a HEAD request, so curl -I looks like a fault on a healthy server.

Worth knowing before a maintenance window: bring DocuWare up first, or restart the proxy afterwards.

Note
DocuWare answers "Invalid redirect_uri"

The redirect URLs in App Registration do not match the address the browser is using. Compare them character by character, including https:// and any port.

Note
Users are signed out after an hour

A session lasts exactly as long as the DocuWare access token, which App Registration sets. Users are sent back to DocuWare and returned without seeing anything, as long as their DocuWare session is still alive. Change Access token lifetime in App Registration if you want longer.