Created 07-14-2025 11:32 AM
Hello @MattWho ,
I'm new to NIFI and Nifikop but I'm using terraform and helm to deploy NIFI on AKS with nifikop, it works well when configured with single-user-provider and overiding nifiproprites with oidc for azure AD, but when I tried to deploy it with file-user-groups provider all the pods kept running and then getting this error :
Caused by: java.io.FileNotFoundException: ../data/users.xml (No such file or directory)
at java.base/java.io.FileOutputStream.open0(Native Method)
at java.base/java.io.FileOutputStream.open(FileOutputStream.java:289)
at java.base/java.io.FileOutputStream.<init>(FileOutputStream.java:230)
at java.base/java.io.FileOutputStream.<init>(FileOutputStream.java:179)
at jakarta.xml.bind.helpers.Abs
and this is my helm chart :
# nifi.security.user.login.identity.provider=single-user-provider
# nifi.security.user.authorizer=single-user-authorizer
nifiProperties:
overrideConfigs: |
nifi.initial.admin.identity = h.nechi@***********.com
nifi.security.user.login.identity.provider=
nifi.security.user.authorizer=managed-authorizer
nifi.sensitive.props.key=ari***********9
nifi.sensitive.props.algorithm=NIFI_PBKDF2_AES_GCM_256
nifi.web.https.port=8443
nifi.remote.input.secure=true
nifi.cluster.protocol.is.secure=true
nifi.web.proxy.context.path=/
nifi.registry.web.proxy.context.path=/nifi-registry
nifi.registry.web.https.host=nifi-registry.******.com
nifi.registry.web.https.port=8443 nifi.security.user.oidc.discovery.url=https://login.microsoftonline.com/*******/v2.0/.well-known/openid-configuration
nifi.security.user.oidc.client.id=dbf698d9-8dec-4e9d-b6d9-b7c7ee8ce694
nifi.security.user.oidc.client.secret=P****************************N
nifi.security.identity.mapping.pattern.dn=CN=([^,]*)(?:, (?:O|OU)=.*)?
nifi.security.identity.mapping.value.dn=$1
nifi.security.identity.mapping.transform.dn=NONE
nifi.security.user.oidc.claim.identifying.user=email
nifi.security.user.oidc.connect.timeout=5 secs
nifi.security.user.oidc.read.timeout=5 secs
# -- A ConfigMap ref to override the default nifi properties
# see
# -- List of allowed HTTP Host header values to consider when NiFi is running securely and will be receiving
# requests to a different host[:port] than it is bound to. Operator will generate comma separated string from list
# https://nifi.apache.org/docs/nifi-docs/html/administration-guide.html#web-properties
webProxyHosts:
- nifi.********.com
- nifi-registry.*********.com
- 4.***.7
# -- In case `cluster.externalServices` contains a service of type `NodePort` and NiFi UI/API needs to be accessed over it,
# this option will add host:nodePort to the `webProxyHosts` list inside `NiFiCluster`.
# Note: When adding webProxyHosts as host:port, NiFi will also create entry for host as valid host header.
webProxyNodePorts:
enabled: false
hosts: []
# - 172.40.120.118
# - domain-pointing-to-k8s-node
# -- Nifi security client auth
needClientAuth: false
# -- You can override individual properties in conf/bootstrap.conf
# https://nifi.apache.org/docs/nifi-docs/html/administration-guide.html#bootstrap_properties
bootstrapProperties:
overrideConfigs: |
java.arg.4=-Djava.net.preferIPv4Stack=true
java.arg.log4shell=-Dlog4j2.formatMsgNoLookups=true
nifiJvmMemory: "512m"
# -- Defines configurations for nodes which can be used in list of nodes in cluster.
# See: https://konpyutaika.github.io/nifikop/docs/5_references/1_nifi_cluster/3_node_config
nodeConfigGroups:
default-group:
isNode: true
# Extra volumes to add to the Pod spec.
# See https://konpyutaika.github.io/nifikop/docs/5_references/1_nifi_cluster/3_node_config#externalvolumeconfig
externalVolumeConfigs:
- name: custom-truststore-volume
mountPath: /opt/nifi/nifi-current/custom-truststore
secret:
secretName: nifi-custom-truststore
imagePullPolicy: IfNotPresent
serviceAccountName: "default"
resourcesRequirements:
limits:
cpu: 2
memory: 3Gi
requests:
cpu: 1
memory: 1Gi
# -- Defines the list of nodes in the cluster with their id's and config to apply.
# See https://konpyutaika.github.io/nifikop/docs/5_references/1_nifi_cluster#nificlusterspec
nodes:
- id: 1
nodeConfigGroup: "default-group"
- id: 2
nodeConfigGroup: "default-group" # Reference the same group or a different one if needed
- id: 3
nodeConfigGroup: "default-group"
propagateLabels: true
# -- The number of minutes the operator should wait for the cluster to be successfully deployed before retrying
retryDurationMinutes: 10
# -- https://konpyutaika.github.io/nifikop/docs/5_references/1_nifi_cluster/6_listeners_config
listenersConfig:
# -- List of internal ports exposed for the nifi container. The `type` of port has specific meaning, see:
# https://konpyutaika.github.io/nifikop/docs/5_references/1_nifi_cluster/6_listeners_config#internallistener
internalListeners:
- type: "https"
name: "https"
containerPort: 8443
- type: "cluster"
name: "cluster"
containerPort: 6007
- type: "s2s"
name: "s2s"
containerPort: 10000
# If enabling monitoring, you need to have a port named prometheus as below
- type: "prometheus"
name: "prometheus"
containerPort: 9090
# -- Provides the SSL configuration for the cluster, can be fully user provided, user provided CA or auto generated
# with cert-manager. See: https://konpyutaika.github.io/nifikop/docs/3_manage_nifi/1_manage_clusters/1_deploy_cluster/4_ssl_configuration
sslSecrets:
create: true
tlsSecretName: nifi-cluster-certs
# -- Additional k8s services to create and target internal listener ports. Ingress will use these to route traffic to
# the cluster
externalServices:
- name: "nifi-cluster-lb"
spec:
type: LoadBalancer
portConfigs:
- port: 8443
internalListenerName: "https"
metadata:
labels: {}
annotations: {}
serviceAnnotations: {}
ingress:
enabled: true
className: nginx
annotations:
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/use-http2: "true"
nginx.ingress.kubernetes.io/proxy-ssl-server-name: "on"
nginx.ingress.kubernetes.io/proxy-ssl-session-reuse: "off"
nginx.ingress.kubernetes.io/proxy-ssl-verify: "off"
hosts:
- host: nifi.*********.com
paths:
- path: /
pathType: Prefix
backend:
# this needs to match the externalServices config above
service:
name: "nifi-cluster-lb"
port:
number: 8443
tls:
- secretName: nifi-cluster-certs
hosts:
- nifi*******.com
# users:
# - identity: "h.nechi@******.com"
# name: "Heni"
# secretName: "" # Leave empty if not using a Kubernetes secret
# createCert: false # Do not create a certificate for this user
# includeJKS: false # Do not include JKS
# accessPolicies:
# - type: global # Grant admin access
# action: read # Allow read access for admin
# resource: / # Allow access to all resources
# - type: global # Grant admin access
# action: write # Allow write access for admin
# resource: / # Allow access to all resources
# -- Configure user groups. Each will result in the creation of a `NiFiUserGroup` CRD in k8s, which the operator
# takes and applies to each nifi configuration.
# See all properties here: https://konpyutaika.github.io/nifikop/docs/5_references/6_nifi_usergroup
userGroups: []
# - name: "basic-user-group"
# identity is an optional field. It defaults to the CRD '<namespace>-<name>'.
# identity: "My Special Group"
# # Users listed here should match the identity of users provided via the `users` configuration
# users:
# - name: CN=first last, OU=Apache NiFi, O=Apache, L=Santa Monica, ST=CA, C=US
# accessPolicies:
# # type is either "global" or "component"
# - type: global
# # action is either "read" or "write"
# action: read
# resource: /counters
# # These should all be used if type is "component"
# componentType: ""
# componentId: ""
# -- A list of extra Kubernetes manifest with Helm template support, to apply
authorizers.xml
<authorizers>
<userGroupProvider>
<identifier>file-user-group-provider</identifier>
<class>org.apache.nifi.authorization.FileUserGroupProvider</class>
<property name="Users File">../data/users.xml</property>
<property name="Legacy Authorized Users File"></property>
<property name="Initial User Identity admin">nifi-cluster-controller</property>
<property name="Initial User Identity 1">nifi-cluster-1-node.nifi-cluster-headless.nifi.svc.cluster.local</property>
<property name="Initial User Identity 2">nifi-cluster-2-node.nifi-cluster-headless.nifi.svc.cluster.local</property>
<property name="Initial User Identity 3">nifi-cluster-3-node.nifi-cluster-headless.nifi.svc.cluster.local</property>
</userGroupProvider>
<accessPolicyProvider>
<identifier>file-access-policy-provider</identifier>
<class>org.apache.nifi.authorization.FileAccessPolicyProvider</class>
<property name="User Group Provider">file-user-group-provider</property>
<property name="Authorizations File">../data/authorizations.xml</property>
<property name="Initial Admin Identity">nifi-cluster-controller</property>
<property name="Legacy Authorized Users File"></property>
<property name="Node Identity 1">nifi-cluster-1-node.nifi-cluster-headless.nifi.svc.cluster.local</property>
<property name="Node Identity 2">nifi-cluster-2-node.nifi-cluster-headless.nifi.svc.cluster.local</property>
<property name="Node Identity 3">nifi-cluster-3-node.nifi-cluster-headless.nifi.svc.cluster.local</property>
<property name="Node Group"></property>
</accessPolicyProvider>
<authorizer>
<identifier>managed-authorizer</identifier>
<class>org.apache.nifi.authorization.StandardManagedAuthorizer</class>
<property name="Access Policy Provider">file-access-policy-provider</property>
</authorizer>
</authorizers>
nifi.propreties :
# nifi.security.identity.mapping.pattern.dn=^CN=(.*?), OU=(.*?), O=(.*?), L=(.*?), ST=(.*?), C=(.*?)$
# nifi.security.identity.mapping.pattern.kerb=^(.*?)/instance@(.*?)$
# nifi.security.identity.mapping.value.dn=$1@$2
# nifi.security.identity.mapping.value.kerb=$1@$2
nifi.administrative.yield.duration=30 sec
nifi.authorizer.configuration.file=./conf/authorizers.xml
nifi.bored.yield.duration=10 millis
nifi.cluster.firewall.file=
nifi.cluster.flow.election.max.candidates=
nifi.content.repository.archive.enabled=true
nifi.content.repository.archive.max.retention.period=3 days
nifi.content.repository.archive.max.usage.percentage=85%
nifi.content.repository.directory.default=../content_repository
nifi.content.repository.implementation=org.apache.nifi.controller.repository.FileSystemRepository
nifi.content.viewer.url=../nifi-content-viewer/
nifi.database.directory=../data/database_repository
nifi.documentation.working.directory=./work/docs/components
nifi.flow.configuration.archive.dir=../data/archive/
nifi.flow.configuration.archive.enabled=true
nifi.flow.configuration.archive.max.count=
nifi.flow.configuration.archive.max.storage=500 MB
nifi.flow.configuration.archive.max.time=30 days
nifi.flow.configuration.file=../data/flow.json.gz
nifi.flowcontroller.autoResumeState=true
nifi.flowcontroller.graceful.shutdown.period=10 sec
nifi.flowfile.repository.always.sync=false
nifi.flowfile.repository.checkpoint.interval=2 mins
nifi.flowfile.repository.directory=../flowfile_repository
nifi.flowfile.repository.implementation=org.apache.nifi.controller.repository.WriteAheadFlowFileRepository
nifi.flowfile.repository.partitions=256
nifi.flowservice.writedelay.interval=500 ms
nifi.h2.url.append=;LOCK_TIMEOUT=25000;WRITE_DELAY=0;AUTO_SERVER=FALSE
nifi.kerberos.krb5.file=
nifi.kerberos.service.keytab.location=
nifi.kerberos.service.principal=
nifi.kerberos.spnego.authentication.expiration=12 hours
nifi.kerberos.spnego.keytab.location=
nifi.kerberos.spnego.principal=
nifi.login.identity.provider.configuration.file=./conf/login-identity-providers.xml
nifi.nar.library.directory=./lib
nifi.nar.working.directory=./work/nar/
nifi.provenance.repository.always.sync=false
nifi.provenance.repository.buffer.size=100000
nifi.provenance.repository.compress.on.rollover=true
nifi.provenance.repository.debug.frequency=1000000
nifi.provenance.repository.directory.default=../provenance_repository
nifi.provenance.repository.encryption.key.id=
nifi.provenance.repository.encryption.key.provider.implementation=
nifi.provenance.repository.encryption.key.provider.location=
nifi.provenance.repository.encryption.key=
nifi.provenance.repository.implementation=org.apache.nifi.provenance.WriteAheadProvenanceRepository
nifi.provenance.repository.index.shard.size=500 MB
nifi.provenance.repository.index.threads=2
nifi.provenance.repository.indexed.attributes=
nifi.provenance.repository.indexed.fields=EventType, FlowFileUUID, Filename, ProcessorID, Relationship
nifi.provenance.repository.journal.count=16
nifi.provenance.repository.max.attribute.length=65536
nifi.provenance.repository.max.storage.size=8 GB
nifi.provenance.repository.max.storage.time=10 days
nifi.provenance.repository.query.threads=2
nifi.provenance.repository.rollover.size=100 MB
nifi.provenance.repository.rollover.time=30 secs
nifi.python.command=python3
nifi.python.extensions.source.directory.default=/opt/nifi/nifi-current/python/extensions
nifi.python.framework.source.directory=./python/framework
nifi.python.logs.directory=./logs
nifi.python.max.processes.per.extension.type=10
nifi.python.max.processes=100
nifi.python.working.directory=./work/python
nifi.queue.swap.threshold=20000
nifi.registry.web.https.host=nifi-registry.*****.com
nifi.registry.web.https.port=8443
nifi.registry.web.proxy.context.path=/nifi-registry
nifi.remote.input.host=nifi-cluster-2-node.nifi-cluster-headless.nifi.svc.cluster.local
nifi.remote.input.http.enabled=true
nifi.remote.input.http.transaction.ttl=30 sec
nifi.remote.input.secure=true
nifi.remote.input.socket.port=10000
nifi.security.identity.mapping.pattern.dn=CN=([^,]*)(?:, (?:O|OU)=.*)?
nifi.security.identity.mapping.transform.dn=NONE
nifi.security.identity.mapping.value.dn=$1
nifi.security.keyPasswd=nP9d6E7rrzfAHz0U
nifi.security.keystore=/var/run/secrets/java.io/keystores/server/keystore.jks
nifi.security.keystorePasswd=nP9d6E7rrzfAHz0U
nifi.security.keystoreType=JKS
nifi.security.needClientAuth=false
nifi.security.ocsp.responder.certificate=
nifi.security.ocsp.responder.url=
nifi.security.truststore=/var/run/secrets/java.io/keystores/server/truststore.jks
nifi.security.truststorePasswd=nP9d6E7rrzfAHz0U
nifi.security.truststoreType=JKS
nifi.security.user.authorizer=managed-authorizer
nifi.security.user.knox.audiences=
nifi.security.user.knox.cookieName=hadoop-jwt
nifi.security.user.knox.publicKey=
nifi.security.user.knox.url=
nifi.security.user.login.identity.provider=
nifi.security.user.oidc.claim.identifying.user=email
nifi.security.user.oidc.client.id=dbf698d9******694
nifi.security.user.oidc.client.secret=PB**********OcwN
nifi.security.user.oidc.connect.timeout=5 secs
nifi.security.user.oidc.discovery.url=https://login.microsoftonline.com/28a********6d/v2.0/.well-known/openid-configuration
nifi.security.user.oidc.preferred.jwsalgorithm=
nifi.security.user.oidc.read.timeout=5 secs
nifi.sensitive.props.additional.keys=
nifi.sensitive.props.algorithm=NIFI_PBKDF2_AES_GCM_256
nifi.sensitive.props.key.protected=
nifi.sensitive.props.key=***
nifi.sensitive.props.provider=BC
nifi.state.management.configuration.file=./conf/state-management.xml
nifi.state.management.embedded.zookeeper.properties=./conf/zookeeper.properties
nifi.state.management.embedded.zookeeper.start=false
nifi.state.management.provider.cluster=zk-provider
nifi.state.management.provider.local=local-provider
nifi.swap.in.period=5 sec
nifi.swap.in.threads=1
nifi.swap.manager.implementation=org.apache.nifi.controller.FileSystemSwapManager
nifi.swap.out.period=5 sec
nifi.swap.out.threads=4
nifi.templates.directory=../data/templates
nifi.ui.autorefresh.interval=30 sec
nifi.ui.banner.text=
nifi.variable.registry.properties=
nifi.web.http.host=
nifi.web.http.network.interface.default=
nifi.web.http.port=
nifi.web.https.host=nifi-cluster-2-node.nifi-cluster-headless.nifi.svc.cluster.local
nifi.web.https.network.interface.default=
nifi.web.https.port=8443
nifi.web.jetty.threads=200
nifi.web.jetty.working.directory=./work/jetty
nifi.web.proxy.context.path=/
nifi.web.proxy.host=nifi-cluster-headless.nifi.svc.cluster.local:8443,nifi-cluster-2-node.nifi-cluster-headless.nifi.svc.cluster.local:8443,nifi-cluster-headless.nifi.svc:8443,nifi-cluster-2-node.nifi-cluster-headless.nifi.svc:8443,nifi-cluster-headless.nifi:8443,nifi-cluster-2-node.nifi-cluster-headless.nifi:8443,nifi-cluster-headless:8443,nifi-cluster-2-node.nifi-cluster-headless:8443,nifi-cluster-2-node:8443,nifi.****.com,nifi-registry.****.com,4.178.238.7
nifi.web.war.directory=./lib
nifi.zookeeper.auth.type=
nifi.zookeeper.connect.string=nifi-cluster-zookeeper:2181
nifi.zookeeper.connect.timeout=3 secs
nifi.zookeeper.kerberos.removeHostFromPrincipal=
nifi.zookeeper.kerberos.removeRealmFromPrincipal=
nifi.zookeeper.root.node=/cluster
and login-identity-provider is technically empty/all commented out
I don't know what am doing wrong!
thank you for your help!
Created 07-15-2025 10:17 AM
@HeniNechi
Try configuring an absolute path for the location of both the users.xml (generated by file-user-group-provider) and authorizations.xml (generated by the file-access-policy-provider) files instead of using "../data/". Make sure that the absolute path is accessible by yoru NiFi service user and that That service provide has permission to allow it to create the users.xml and authorizations.xml files in that directory path.
NiFi will fail to start if the authorizers.xml fails to successfully execute which is what you are encountering. I suspect a permission issue or similar that is preventing NiFi from being able to create the necessary files in the defined directory path.
Please help our community grow. If you found any of the suggestions/solutions provided helped you with solving your issue or answering your question, please take a moment to login and click "Accept as Solution" on one or more of them that helped.
Thank you,
Matt
Created 07-15-2025 10:17 AM
@HeniNechi
Try configuring an absolute path for the location of both the users.xml (generated by file-user-group-provider) and authorizations.xml (generated by the file-access-policy-provider) files instead of using "../data/". Make sure that the absolute path is accessible by yoru NiFi service user and that That service provide has permission to allow it to create the users.xml and authorizations.xml files in that directory path.
NiFi will fail to start if the authorizers.xml fails to successfully execute which is what you are encountering. I suspect a permission issue or similar that is preventing NiFi from being able to create the necessary files in the defined directory path.
Please help our community grow. If you found any of the suggestions/solutions provided helped you with solving your issue or answering your question, please take a moment to login and click "Accept as Solution" on one or more of them that helped.
Thank you,
Matt
Created 07-15-2025 12:10 PM
Hello @MattWho,
You are absolutely right, but I took the easy way out and created an external volume ./data and mounted and now it works as a workarround.
Now am having another problem with oidc and setting my intial admin in the authorizer as my Azure AD email, should I create another topic for that?
Created 07-15-2025 02:17 PM
Preferred to have new question for unique questions, but....
Keep in mind these things when it comes to user identities and authorizations:
1. user identities are case sensitive in NiFi. So the user identity from oidc must match exactly the initial admin user identity you passed to the file-user-group-provider and the file-access-policy-provider.
2. The file-user-group-provider will only generate the users.xml file if it does NOT already exist. So if you edit the configuration of the file-user-group-provide after the users.xml already exists, those change will not be made to that existing users.xml file. (remove it and restart so it gets created again)
3. The file-access-policy-provider will only generate the authorizations.xml file if it does not exist. It also will not modify an already existing authorizations.xml file if you make modifications to the provider.
4. Additional user identities and authorization post accessing your NiFi with your initial admin are done directly with the NiFi UI. Those additions made from the UI will be persisted in the users.xml and authorizations.xml files
If above does not help, please start a new community question with the details of your issue.
Please help our community grow. If you found any of the suggestions/solutions provided helped you with solving your issue or answering your question, please take a moment to login and click "Accept as Solution" on one or more of them that helped.
Thank you,
Matt